重學JS系列: new 操作符,和實現一個 new 操作符

  1. new 的特點
  2. 如果實現一個 new 操作符

一、new 運算符

new運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。new 關鍵字會進行如下的操作:

  • 創建一個空的 js 對象{}
  • 鏈接該對象(即設置該對象的構造函數)到另一個對象 ;
  • 將步驟1新創建的對象作爲this的上下文 ;
  • 如果該函數沒有返回對象,則返回this
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

var car1 = new Car('Eagle', 'Talon TSi', 1993);

console.log(car1.make);
// expected output: "Eagle"

二、手工實現一個 new 操作符

實現步驟

  1. 上面說了 new操作符會返回一個對象, 所以我們需要在創建一個 object
  2. 那麼我們需要將構造函數的的原型 設置到另一個對象上
  3. 將創建的對象 作爲this的上下文
  4. 有屬性返回屬性, 沒有則返回 this
function  create(Con, ...args) {
    let obj = {};
    Object.setPrototypeOf(obj, Con.prototype)
    let result = Con.apply(obj, args)
    return result instanceof Object ? result : obj
}

上面的函數 第一個參數作爲構造函數傳入, 接下來的參數被構造函數使用
然後按上面的1、2、3、4步驟實現

  • 創建一個 空對象
  • 將 構造函數的原型 設置給 空對象。 等用於 obj.__proto__ = Con.prototype
  • 將 obj 綁定到構造函數上, 並且通過剩餘參數傳入
  • 最後 判斷 返回值是否爲對象, 如果爲對象 則 返回使用構造函數的result, 否則就返回 obj

那我們來看看最後實現的效果吧

function Test(name, age) {
    this.name = name
    this.age = age
}

Test.prototype.intr = function () {
    console.log(`my name is ${this.name}, i'm ${this.age} years old`)
}

const me = create(Test, 'gavin', '21')
console.log(me.name)  //output: gavin
console.log(me.age)  //output: 21

me.intr()  // my name is gavin, i'm 21 years old``
參考
web docs: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new
掘金 yck: https://juejin.im/post/5c7b963ae51d453eb173896e
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章