動態原型模式
? 以建構式模式組合原型模式在目前看來已經很完美了,硬要挑出它的缺點的話就是封裝性差了點,動態原型模式正是致力于解決這個問題的一個方案:
function Person(name, age, sex){
this.name = name
this.age = age
this.sex = sex
Person.prototype.sleep = function(){
alert(this.name + '睡覺了')
}
}
? 將修改原型屬性的代碼一塊寫進建構式里面,但是上面的代碼還有一個問題,如果每創建出一個實體,那么就會為 Person.prototype.sleep 重新賦值,這是完全沒有必要的,因此下面對此做出了一點修改:
function Person(name, age, sex){
this.name = name
this.age = age
this.sex = sex
if (typeof this.sleep !== 'function'){
Person.prototype.sleep = function(){
alert(this.name + '睡覺了')
}
}
}
? typeof this.sleep !== 'function' 這句判斷只會在第一次創建實體的時候為真,由于在創建第一次實體我們就為它的原型物件的屬性 sleep 賦值了一個方法,所以在第二次創建新的實體的時候,這個 sleep 的型別自然為 function,判斷也就不成立,也就不會再次為原型物件重復無意義的賦值操作,
? 那么能否再次簡化代碼,在內部使用字面量的方法重寫 Person 的原型呢?
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
if (typeof this.sleep !== 'function') {
Person.prototype = {
constructor: this,
sleep: function() {
alert(this.name + '睡覺了')
}
}
}
}
? 上面的代碼看似沒什么問題,實則有個致命的錯誤:
const person1 = new Person('小明', 22, '男')
const person2 = new Person('小紅', 22, '女')
console.log(person1.sleep) // undefined
console.log(person2.sleep) // f()
? 因為在第一次創建實體的時候,內部的 if 陳述句在進行它的第一次判斷時,第一次創建的實體的原始的原型物件(在創建Person時自動創建的原型物件)就已經存在,所以 person1 內部的原型物件的指標指向的原型物件仍舊是原始的原型物件,在第二次創建出實體 person2 的時候,它的原型指標指向的才是 if 陳述句中我們重寫的新的原型物件,這也就造成了在 person1 訪問不到原型物件的屬性 sleep,而 person2 卻能夠正常訪問到屬性 sleep,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/253895.html
標籤:JavaScript
上一篇:建構式+原型模式
下一篇:寄生建構式模式
