javascript new 的原理

昨晚看了一篇模拟实现 js new 的文章,今天复盘一下javascript

 

function a(){
    this.b = 'bb';
}
a.prototype.c = 'cc';

var aa = new a();

new 其实作了三件事情,首先它确定是建立了一个对象java

2.将 a 的prototype属性对象经过引用传递赋值给 aa.__proto__ ,至关于:aa.__proto__ = a.prototypees6

进一步证明一下:app

第三件事:用对象 aa 调用函数 a,从而使 a 内部的 this 指向 aa,即:函数

a.apply(aa)this

 这样 aa 就有了属性 bprototype

这样咱们就用上面的三步“生产”出了一个和 new 效果同样的对象 bb;3d

 

以上就是 new 的基本原理了,但还有一些小细节 :code

1. 函数a 若是有参数对象

2. 函数 a 若是有返回值

1 : 比较简单,修改第三步为 a.apply(bb , [arg1, arg2, ...])  就能够了

2 : 分两种状况:

    a.返回值类型为基本类型: string number null undefined boolean symbol 

    b.返回值为对象 即,typeof 等于 'object' 或 'function' ,这里面包含了 Array、Date、RegExp、Error 等。。。

状况 a 是咱们上面讲的普通状况,

可是当咱们 new 一个返回值为对象的函数时,js 不会执行上面的那些操做,而是执行函数并返回函数的发回值 即:

new a();  和 a(); 的效果是同样的:

 

因此若是要本身模拟一个 new 函数能够这样写:

function newOperator(ctor){
    if(typeof ctor !== 'function'){
      throw 'newOperator function the first param must be a function';
    }
    //es6 new.target 指向构造函数(这个没有细究)
    newOperator.target = ctor;

    //这里能够经过 Object.create 将第一二步合成一步
    var newObj = Object.create(ctor.prototype);
    var argsArr = [].slice.call(arguments);
    argsArr.shift();
    var ctorReturnResult = ctor.apply(newObj, argsArr);
    if(typeof ctorReturnResult === 'object' && ctorReturnResult !== null){
        return ctorReturnResult;
    }
    if(typeof ctorReturnResult === 'function'){
        return ctorReturnResult;
    }
    return newObj;
}

 

 

固然 js 也赋予了 prototype __proto__ 这些特殊属性一些特殊做用,

好比 能够用 aa.c  来访问 aa.__proto__.c  前提是 aa 没有 c 这个自有属性,而且不能经过 aa.c 来修改 aa.__proto__.c 即:

aa.c = 'ss' 是不能改变 aa.__proto__.c 的值

 

__________________________________________________________

因此,清楚了  __proto__ 是一个对象引用,而且了解了它的特殊做用 js 的原型链 面向对象 也就明白八成了吧~~!

相关文章
相关标签/搜索