原型链,__proto__和prototype

构造函数,原型和实例的关系:

每个构造函数(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] }

你可能感兴趣的:(原型链,__proto__和prototype)