2019-09-18 new 关键字的实现原理

1.创建一个新对象;

2.将新对象的原型指向构造函数的原型链;

3.将构造函数的this指向新对象,并将初始化时的参数传入;

4.判断构造函数中是否返回了其他对象,如果有返回对象,则将构造函数的返回对象返回;否则返回新对象;

    // 构造函数1,有return
    function Test1 (options) {
        return {
            name: '哈哈',
            opt: options || ''
        };
    }

    // 构造函数2,属性和方法在原型和构造函数上。
    function Test2 (options) {
        this.width = 120;
        this.opt = options || '';
    }
    Test2.prototype.height = 123;

    function _new () {
        // 创建一个新对象;
        var newFunc = {};

        // 构造函数初始化时传入的参数
        var args = Array.prototype.slice.call(arguments, 1);

        // 默认第一个参数为构造函数
        var Func =  arguments[0];

        // 将新对象的原型指向构造函数的原型链;
        // prototype是一个拥有`constructor`内部方法的对象(函数)才有的属性(函数同时也有__proto__,只要是对象就有`__proto__`)。newFunc 不是一个函数,没有`constructor`,没有prototype,只有`__proto__`;
        newFunc.__proto__ = Func.prototype;

        // 将构造函数的this指向新对象;
        var res = Func.apply(newFunc, args);

        // 判断构造函数中是否返回了其他对象,如果有返回对象,则将构造函数的返回对象返回;否则返回新对象;
        if (res && (typeof res === 'object' || typeof res === 'function')) {
            return res;
        }

        return newFunc;
    }

    var test1 = _new(Test1, 'lalala');
    var newTest1 = new Test1('lalala');
    var test2 = _new(Test2, 'lalala');
    var newTest2 = new Test2('lalala');
    console.log('_new', test1);
    console.log('new', newTest1);
    console.log('_new', test2);
    console.log('new', newTest2);
image.png

扩展:

prototype和proto分别是什么?

prototype(显式原型)是对象的一个属性(每个对象都有一个prototype属性),这个属性是一个指针,指向一个对象,通过它可以向对象添加属性和方法。

proto(隐式原型)是对象的一个内置属性,是JS内部使用寻找原型链的属性,也就是说,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着proto依次向上查找。

具体可以查看:https://www.cnblogs.com/Double-Zhang/p/7682211.html

你可能感兴趣的:(2019-09-18 new 关键字的实现原理)