js高級進階——手動實現new操作符

    function Animal(name, age) {
      this.name = name
      this.age = age
      // return {}
    }

    Animal.prototype.sayName = function () {
      console.log("Hello Everyone, I am " + this.name)
    }

    var dog = new Animal('bob', 5)
    dog.sayName() // Hello Everyone, I am bob 
    console.log(dog instanceof Animal) // true

    // object instanceof constructor; instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈

    // new關鍵字我們用函數來實現它的功能,因爲js無法操作js底層關鍵字
    // new關鍵字做了什麼?
    // 1、創建了一個對象
    // 2、創建的實例對象的原型上繼承了構造函數的原型對象
    // 3、將構造函數this上的屬性掛載到新創建的對象上(新創建的對象作爲this的上下文)
    // 4、如果構造函數沒有返回對象,則返回新創建的對象;如果有返回新對象,那麼new之後返回的就是新對象

    function _new(fn) {
      var args = [].slice.apply(arguments, [1])
      var obj = {}
      Object.setPrototypeOf(obj, fn.prototype)
      var result = fn.apply(obj, args)
      return result instanceof Object ? result : obj
    }

    var cat = _new(Animal, 'alice', 3)
    cat.sayName() // Hello Everyone, I am alice
    console.log(cat instanceof Animal) // true

    // ECMAScript6的實現
    function _es6new(fn, ...args) {
      let obj = Object.create(fn.prototype)
      let result = fn.call(obj, ...args)
      return result instanceof Object ? result : obj
    }

    var rabbit = _es6new(Animal, 'pace', 4)
    rabbit.sayName() // Hello Everyone, I am pace
    console.log(rabbit instanceof Animal) // true

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章