实现new操作符

185 阅读1分钟

使用new 📔

      function Car(make, model, year) {
            this.make = make;
            this.model = model;
            this.year = year;
        }
        Car.prototype.sall = function () {
            console.log(this.model + '102万元')
        }

        const car1 = new Car('Eagle', 'Talon TSi', 1993);
        console.log(car1) //  Car {make: "Eagle", model: "Talon TSi", year: 1993}make: 	             "Eagle"model: "Talon TSi"year: 1993__proto__: Object}
        car1.sall() // Talon TSi102万元

思路:通过上面的例子🌰

  1. new实现了什么(结果)

    通过new创造出了一个新的实例,car1,它是一个对象,并且有构造函数Car的属性和方法

  2. new是怎么做的(过程)

    • 创造了一个新对象,且返回了这个对象
    • 让构造函数Carthis指向了car1,实现了让car1继承Car的属性和方法
    • 接收了参数,并赋值

实现代码✍

  • 创造了一个新对象,且返回了这个对象

    function mock() {
                let obj = new Object()
                return obj
    }
    
  • 让构造函数Carthis指向了car1

    function mock() {
                let obj = new Object()
                // 拿到函数Car
                let fn = Array.prototype.shift.call(arguments) // 删除并拿到arguments的第一项
                obj.__proto__ = fn.prototype // 改变this的指向
                return obj
    }
    
  • 接收了参数,并赋值

    function mock() {
                let obj = new Object()
                // 拿到函数Car
                let fn = Array.prototype.shift.call(arguments) // 删除并拿到arguments的第一项
                obj.__proto__ = fn.prototype // 改变this的指向
                let parma = Array.prototype.slice.call(arguments) // 将arguments转化为数组
                fn.apply(obj, parma)
                return obj
    }
    
  • 优化(如果构造函数返回的是基本数据类型或者Null等)

     function Car(make, model, year) {
                this.make = make;
                this.year = year;
                return 'hello world
     }
     // 虽然有返回值,但是相当于没有对数据进行处理
    // 所以需要判断返回值,如果是一个对象,我们就返回这个对象,如果没有,我们该返回什么{}
       function mock() {
                let obj = new Object()
                let fn = Array.prototype.shift.call(arguments) // 删除并拿到arguments的第一项
                obj.__proto__ = fn.prototype
                let parma = [].slice.call(arguments)
                let result = fn.apply(obj, parma)
                return Object.prototype.toString.call(obj).slice(8, -1) === 'object' ? result : obj
        }