構(gòu)造函數(shù),原型和實例的關(guān)系:
每個構(gòu)造函數(shù)(constructor)都有一個原型對象(prototype),原型對象都包含一個指向構(gòu)造函數(shù)的指針,而實例(instance)都包含一個指向原型對象的內(nèi)部指針。
__proto__和prototype的區(qū)別
prototype 只有函數(shù)才有的屬性
__proto__是每一個對象都有的屬性
原型鏈
由于 __proto__是任何對象都有的屬性,而js,萬物皆對象,所以會形成一條__proto__連起來的鏈條,遞歸訪問__proto__必須最終到頭,并且值為null。
- 一般來說,__proto__ === constructor.prototype
- 當(dāng)訪問一個屬性,會首先檢索自身的屬性,若自身沒有,則會沿著__proto__向上尋找,一層一層地尋找,直到尋到
null,這里的原型鏈就是實例對象的__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; // 注意這個
B.prototype = new A('b');
var c = new B();
這是沒有設(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的實例在原型鏈上不混亂)
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] }