函数实现new的功能

589 阅读2分钟

函数实现new的功能

要实现一个类似new操作符的函数首先我们来分析一下 new关键字都干了些什么 先来看个demo

        function Person(name,age) {
            this.name = name,
            this.age = age
        }
        Person.prototype.sayName = function() {
            console.log(this.name);
        }

        let p = new Person('zhangsan',18)
        console.log('p :>> ', p);
    
    // 打印结果如下:
        Person {name: "zhangsan", age: 18}
        age: 18
        name: "zhangsan"
        __proto__:
        sayName: ƒ ()
        constructor: ƒ Person(name,age)
        __proto__: Object

我们可以看到,当构造函数的执行结果没有返回值(返回undefined)时,new关键字干的事情可以总结为以下几点:

  1. 以构造函数的原型为原型创建了一个新的实例
  2. 把构造函数身上的属性和方法添加到新的实例身上
  3. 返回创建的新实例

这是构造函数没有返回值的例子,其实返回值为非Object类型时都是这样的,接下来我们再来看下当返回值为对象类型时会发生什么

        function Person(name,age) {
            this.name = name,
            this.age = age
            return {
                height: 181
            }
        }

        Person.prototype.sayName = function() {
            console.log(this.name);
        }
        let p = new Person('zhangsan',18)
        console.log('p :>> ', p);
        
        // 打印结果如下
        p :>>  {height: 181}

我们可以看到当构造函数的返回结果为一个对象时,经new关键字返回的仍是这个对象

经过上面的总结,我们就做出了下面的简单实现

    function _new(obj, ...args) {
         // 1. 以传入的构造函数的原型为原型创建一个新的实例
         const newObj = Object.create(obj.prototype)
         // 2. 把构造函数的身上的属性和方法赋值给新实例
         const result =  obj.apply(newObj, args)
         // 3. 判断执行构造函数的返回结果 如果是对象则返回该对象 否则返回新实例
         return result instanceof Object ? result : newObj
    }

总结

实现一个类似new操作符的函数需要做的事:

  1. 以构造函数的原型为原型创建一个新的实例
  2. 把构造函数身上的属性和方法添加到新的实例身上
  3. 如果构造函数的执行结果为一个对象则返回该对象,否则返回上述新创建的实例