邂逅new,实现new

2,749 阅读4分钟

为了更好的理解后面的内容,我们先来了解一些前置知识吧!

构造函数和普通函数的区别

构造函数:

使用一个函数来初始化对象,并配合new使用,则我们称这个函数为构造函数

普通函数

作为一个函数,除了构造函数之外就是普通函数了,详细大家用的比我熟练

构造函数和普通函数的区别

二者到底有什么区别呢?

语法上没有区别!!!唯一的区别就是使用上的区别,使用上如何区别二者呢?使用了函数前面有一个new关键字,那就是构造函数,只要记住这一点就行了!

普通函数怎么使用呢?我就不在关公面前耍大刀了

我们来看一下构造函数怎么使用吧!

function Person(name, age){
    this.name = "codingkid";
    this.age = 18;
}
var person = new Person();

相信大家都这样用过,new关键字在很多其他语言也都存在,但内部发生了什么呢?

  1. 创建一个空对象
var person = {}
  1. this变量指向对象p
Person.call(p)

关于call的用法并不难,可以参考我的文章

  1. person除了有了Person函数中定义的变量外,还继承了Person()的原型,也就是可以使用Person()中原型的变量和方法,关于原型和原型链的文章太多了,比如这篇就很不错
person._proto_ = Person.prototype
  1. 执行构造函数Person()内的代码 由此可看构造函数就是比普通函数多了些操作,这些多的操作无疑和new关键字有很大的关系

不过需要细想几个问题

  1. 对的,第一个是关于this的问题,进行了上述过程后,构造函数中的this绑定了person对象,但普通函数却没有绑定对象,其实函数本质上也就相当于一个对象的属性,在全局下声明的函数相当于省略了window,不过是window的一个属性,所以调用时会指向window,在其他对象中声明的函数可类似此过程。
  2. 构造函数会返回一个新的对象,所以不会在构造函数中使用return语句,如果使用了return语句,则会根据return值的类型而有所不同,原本没有如return会返回一个对象,对象是一个应用类型,所以当显示使用return返回应用类型的话,会生效,否则会失效,依旧返回声称的对象。普通函数的return正常用就行了。

以上过程算是与new相识,与new邂逅了吧吧吧吧吧吧吧

实现new

其实经过邂逅后,实现起来就比较简单了,不要感到害怕(大神见到的话就当是对我自己说的吧),我们依旧用上面的栗子,我们要彻底把这个栗子吃掉,然后消化,再把糟粕舍弃,怎么舍弃就看你自己了

function Person(name, age){
    this.name = "codingkid";
    this.age = 18;
}
// var person = new Person();
// 我们自己实现另一个new
var person = ourNew(Person(),name,age)

我们只要让ourNew实现new的功能就可以了,和官方的new使用形式不同,那也只是语法糖上的差异了,对我们对new的理解不影响,如何写出ourNew呢,我把代码给你,你一定会发现,幸好当初邂逅了new

function ourNew(context) {	
    // 1.创建一个空对象
    var person = new Object();
    // 2.取出构造函数
    var constructor = [].shift.call(arguments);
    // 3.继承构造函数的原型
    person._proto_ = constructor.prototype;
    // 4.为新建的对象调用构造函数,生成内部属性
    constructor.apply(person, arguments);
    // 5.返回对象
    return person;
}

看到这里应该表扬一下自己,不过别急,我们还要完善一下,还记得关于返回值的问题吧!看下面这一版代码

function ourNew(context) {	
    // 1.创建一个空对象
    var person = new Object();
    // 2.取出构造函数,假设此构造函数有返回值
    var constructor = [].shift.call(arguments);
    // 3.继承构造函数的原型
    person._proto_ = constructor.prototype;
    // 4.为新建的对象调用构造函数,生成内部属性,同时构造函数运行时返回它想返回的值
    var somethingReturned = constructor.apply(person, arguments);
    // 5.返回对象
    return typeof somethingReturnedperson === 'object' ? somethingReturned : person;
}

完美了!!!!!

更多

参考文档

segmentfault.com/a/119000000…

github.com/mqyqingfeng…

本孩加油啊!!!!!!!大人们点赞鼓励一下吧!