構(gòu)造函數(shù),原型和實(shí)例的關(guān)系:
每個(gè)構(gòu)造函數(shù)(constructor)都有一個(gè)原型對(duì)象(prototype),原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例(instance)都包含一個(gè)指向原型對(duì)象的內(nèi)部指針匠璧。
__proto__和prototype的區(qū)別
prototype 只有函數(shù)才有的屬性
__proto__是每一個(gè)對(duì)象都有的屬性
原型鏈
由于 __proto__是任何對(duì)象都有的屬性,而js,萬(wàn)物皆對(duì)象把将,所以會(huì)形成一條__proto__連起來(lái)的鏈條,遞歸訪(fǎng)問(wèn)__proto__必須最終到頭忆矛,并且值為null察蹲。
- 一般來(lái)說(shuō),__proto__ === constructor.prototype
- 當(dāng)訪(fǎng)問(wèn)一個(gè)屬性洪碳,會(huì)首先檢索自身的屬性递览,若自身沒(méi)有,則會(huì)沿著__proto__向上尋找瞳腌,一層一層地尋找绞铃,直到尋到
null
,這里的原型鏈就是實(shí)例對(duì)象的__proto__屬性嫂侍。
function A(name){
this.test = name;
};
A.prototype.getName = function () {
return console.log(this.test);
}
var a = new A('a');
function B() {};
// B.prototype.constructor = B; // 注意這個(gè)
B.prototype = new A('b');
var c = new B();
這是沒(méi)有設(shè)置B.prototype.constructor = B的各種情況的結(jié)果;
c.constructor === function A(name) {
this.test = name;
}
B.prototype.constructor === function A(name) {
this.test = name;
}
B.constructor === function Function() { [native code] }
a.__proto__ === A { getName: [Function] }
new B().__proto__ === A { test: 'b' }
B.prototype === A { test: 'b' }
c.__proto__ === A { test: 'b' }
B.__proto__ === function () { [native code] }
A.__proto__ === function () { [native code] }
B.prototype.__proto__ === A { getName: [Function] }
設(shè)置B.prototype.constructor = B的各種情況的結(jié)果;
(之所以要設(shè)置B.prototype.constructor = B儿捧,是為了使B的實(shí)例在原型鏈上不混亂)
c.constructor === function B() {}
B.prototype.constructor === function B() {}
B.constructor === function Function() { [native code] }
a.__proto__ === A { getName: [Function] }
new B().__proto__ === B { test: 'b', constructor: [Function: B] }
B.prototype === B { test: 'b', constructor: [Function: B] }
c.__proto__ === B { test: 'b', constructor: [Function: B] }
B.__proto__ === function () { [native code] }
A.__proto__ === function () { [native code] }
B.prototype.__proto__ === A { getName: [Function] }