美文网首页
new 操作符具体干了什么

new 操作符具体干了什么

作者: 弱冠而不立 | 来源:发表于2020-11-12 08:43 被阅读0次

    MDN 上描述如下:

    1. 创建一个空的简单Javascript对象 (即{ })
      2. 将构造函数赋给该空对象的constructor
    2. 链接空对象的原型和构造函数的原型 (设置该构造函数的prototype为新创建空对象的 __proto__
    3. 将新创建的对象作为 this 的上下文(即将构造函数的作用域赋给新对象)
    4. 如果该构造函数没有返回对象,则返回 this

    我认为 第二步 应该和网上大多数说的一样,将构造函数的原型传递给新建对象的隐式原型(__proto__),如果是将构造函数直接赋值给新建对象的隐式原型上的 constructor 那么这个构造出来的新对象,还具有原生对象的一些属性。如下图:

    根据MDN和网上参考的一些解释,得出如下实现的代码

        const customNew = (constructor) => {
            let obj = {}
             obj.__proto__ = constructor.prototype
            return function () {
                constructor.apply(obj, arguments)
                return obj
            }
        }
    

    然后让我们来使用一下

        function Person(name, age) {
            this.name = name;
            this.age = age;
        }
    
        Person.prototype.sayName = function() {
            console.log(this.name);
        } 
    
        let person1 = new Person("ming", 12)
        let person2 = customNew(Person)("hong", 11)
        console.log(Person.prototype);
        console.log(person1);
        console.log(person2);
    
    貌似功能都完善得差不多了,但是如果构造函数有返回值的话就会出错了
        function Person(name, age) {
            this.name = name;
            this.age = age;
            return {
                age: this.age
            }
        }
    

    结合构造函数的内部原理:

    1. 在函数体前隐式加上 this = {}
    2. 执行 this.xxx = xxx
    3. 隐式返回 this

    最终代码如下:

        const customNew = (constructor) => {
            //1. 创建一个空的简单Javascript对象 (即{ })
            let obj = {}
            //2. 将构造函数的原型和对象的原型关联
            obj.__proto__ = constructor.prototype
            return function () {
                //3. 为新创建的对象添加属性
                const res = constructor.apply(obj, arguments)
                if(res instanceof Object) { //4. 如果该构造函数没有返回对象,则返回 this
                    return res
                } else {
                    return obj
                } 
            }
        }
    

    具体使用:

    function Foo(name) {
        this.name = name;
    }
    
    let obj = customNew(Foo)("obj");
    console.log(obj);
    

    相关文章

      网友评论

          本文标题:new 操作符具体干了什么

          本文链接:https://www.haomeiwen.com/subject/jiajbktx.html