無(wú)聊就隨便選一個(gè)話題來(lái)寫吧坛悉。
原型鏈
其實(shí)原型鏈在我理解看來(lái)大概就是一段串聯(lián)起來(lái)的關(guān)系鏈
var demoObj = {
a: 2
}
console.log(demoObj.a) //輸出2
//如果新對(duì)象里面不含有該屬性, 會(huì)從 [prototype] 里面去尋找
var newObj = Object.create(demoObj); //新對(duì)象與demoObj建立起關(guān)系
console.log(newObj.a) //同樣輸出2, 因?yàn)閚ewObj的 [prototype] 指向了demoObj
用函數(shù)會(huì)比較直觀:
//創(chuàng)建父類
function Animal() {}
//添加屬性
Animal.prototype.walk = function() {
console.log('walk')
}
//創(chuàng)建子類
function Cat() {}
//引用父類屬性
Cat.prototype = Animal.prototype;
var cat = new Cat();
cat.walk(); //輸出'walk'
這樣的好處就是類似Array之類原生的對(duì)象給我們提供了一些可用的方法,可以給子類繼續(xù)引用使用耙厚。
但是如果原型鏈上存在相同屬性的時(shí)候,可能會(huì)出現(xiàn)一些意想不到的問(wèn)題扇谣。
var demoObj = {
width: 10
};
//創(chuàng)建屬性,設(shè)置不可寫
Object.defineProperty(demoObj, 'height', {
writable: false,
enumerable: true,
configurable: true,
value: 12
};
var newObj = Object.create(demoObj);
console.log(newObj.height); //輸出12;
newObj.height = 22; //賦值
newObj.width = 33; //賦值
console.log(newObj.height, newObj.width); //12, 33
上面的例子蹈胡,如果對(duì)象不存在屬性通熄,而原型鏈上該屬性不可寫,會(huì)發(fā)生以上的情況脱羡。 newObj.width
正常被賦值到了對(duì)象上, console.log(newObj)
會(huì)發(fā)現(xiàn)多了 width
的屬性, 這是正常的現(xiàn)象(叫屏蔽屬性)萝究。但原型鏈上不可寫的時(shí)候, 就觸發(fā)不了了。而且若當(dāng)原型鏈上尋找的設(shè)置有setter的話, 也會(huì)調(diào)用setter的方法, 也同樣添加不了屬性到 newObj
里面锉罐。
prototype的賦值也有些區(qū)別:
function parent() {
this.a = 123;
}
parent.prototype.talk = function() {
console.log(this.a)
}
function child1() {}
function child2() {}
function child3() {}
child1.prototype = parent.prototype;
child2.prototype = new parent();
child3.prototype = Object.create(parent.prototype);
var result1 = new child1();
var result2 = new child2();
var result3 = new child3();
result1.talk(); //輸出undefined
result2.talk(); //輸出123
result3.talk(); //輸出undefined
child1.prototype.hello = function() {
console.log('hello')
}
child3.prototype.goodbye = function() {
console.log('goodbye')
}
result1.hello(); //輸出'hello'
result2.hello(); //輸出'hello'
result3.hello(); //輸出'hello'
result1.goodbye(); //error: result1.goodbye is not a function
result2.goodbye(); //error: result2.goodbye is not a function
result3.goodbye(); //輸出'goodbye'
child2
函數(shù)中new
的方法, 他會(huì)創(chuàng)建 this
對(duì)象, 所以也把 a
屬性也賦值給了 child2.prototype
中帆竹。
child3
和 child1
的最大區(qū)別在于一個(gè)是直接把 parent.prototype
的屬性賦值給了 child1
, 另一個(gè)是使用 Object.create
創(chuàng)建了一個(gè)新的對(duì)象, 不會(huì)發(fā)生引用傳值的問(wèn)題, 引用傳值會(huì)導(dǎo)致修改 child1.prototype
同時(shí)也會(huì)修改父元素的 prototype
, 但是 Object.create
可能會(huì)導(dǎo)致 constructor
屬性丟失, 重新設(shè)置即可。
結(jié)語(yǔ)
其實(shí)構(gòu)造函數(shù)跟原型鏈一起更配脓规。今天就寫這么多吧栽连。