1. 程式人生 > >JavaScript之new的模擬實現

JavaScript之new的模擬實現

開發十年,就只剩下這套架構體系了! >>>   

JavaScript之new的模擬實現

一句話介紹bind: new 運算子建立一個使用者定義的物件型別的例項或具有建構函式的內建物件型別之一   new實現了哪些功能
function Otaku (name , age){
    this.name = name
    this.age = age

    this.habit = 'Games'
}

Otaku.prototype.strength = 60
Otaku.prototype.sayYourName = function(){
    console.log('I am ' + this.name)
}

var person = new Otaku('hy' , 18)

console.log(person.name)
console.log(person.age)
console.log(person.habit)
console.log(person.strength)

person.sayYourName()

由此可以看出,例項person可以:

  1. 訪問到Otaku建構函式裡的屬性
  2. 訪問到Otaku.prototype中的屬性
  初步實現 分析:
  1. 因為new的結果是一個新物件,所以在模擬實現的時候,我們也要建立一個新物件,假設這個新物件叫做obj
  2. 因為obj會具有Otaku建構函式裡的屬性,我們可以使用Otaku.apply(obj,arguments)來給obj新增新的屬性
  3. 例項的__proto__屬性會指向建構函式的prototype,也正是因為建立起這樣的關係,例項可以訪問原型上的屬性
第一版
function objectFactory(){
    var obj = new Object()
    Constructor = [].shift.call(arguments)

    obj.__proto__ = Constructor.prototype

    Constructor.apply(obj , arguments)

    return obj
}

 

這一版中,我們:
  1. 用new Object() 的方式新建了一個物件 obj
  2. 取出第一個引數,就是我們要傳入的建構函式。此外因為shift會修改原陣列,所以arguments 會被去除第一個函式
  3. 將obj的原型指向建構函式,這樣obj就可以訪問到建構函式原型中的屬性
  4. 使用apply,改變建構函式this的指向到新建的物件,這樣obj就可以訪問到建構函式中的屬性了。
  5. 返回obj
  返回值效果實現
function Otaku(name , age){
    this.strength = 60
    this.age = age

    return 'handsome boy';
}

var person = new Otaku('hy', '18');

console.log(person.name) // undefined
console.log(person.habit) // undefined
console.log(person.strength) // 60
console.log(person.age) // 18

第二版

function objectFactory(){
    var obj = {}
    Constructor = [].shift.call(arguments)
    obj.__proto__ = Constructor.prototype
    var ret = Constructor.apply(obj , arguments)
    return typeof ret === 'object' ? ret : obj
}