构造函数,原型和实例的关系:
每个构造函数(constructor)都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针,而实例(instance)都包含一个指向原型对象的内部指针。
__proto__和prototype的区别
prototype 只有函数才有的属性
__proto__是每一个对象都有的属性
原型链
由于 __proto__是任何对象都有的属性,而js,万物皆对象,所以会形成一条__proto__连起来的链条,递归访问__proto__必须最终到头,并且值为null。
- 一般来说,__proto__ === constructor.prototype
- 当访问一个属性,会首先检索自身的属性,若自身没有,则会沿着__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();
这是没有设置B.prototype.constructor = B的各种情况的结果;
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] }
设置B.prototype.constructor = B的各种情况的结果;
(之所以要设置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] }