图解原型链

前言

JavaScript 不包含传统的类继承模型,而是使用 prototype 原型模型。无论什么时候,只要创建了一个新函数,就会为该函数创建一个 prototype 属性,这个属性指向函数的原型对象。

jsobj

原型指针__proto__和原型对象 prototype

1.每个对象都有一个__proto__属性,指向创建该对象的函数的 prototype,即原型对象

obj.__proto__ === Object.prototype // true

2.Object.prototype 是特例,它的__proto__指向的是 null

Object.prototype.__proto__ === null // true

3.对象是通过函数来创建的

Object.__proto__ === Function.prototype // true

4.函数作为 JavaScript 中的一等公民,它既是函数又是对象,函数的原型指向 Function.prototype

var Foo = function() {}
Foo.__proto__ === Function.prototype // true

5.原型对象的 constructor 属性指向 prototype 属性所在函数

Foo.prototype.constructor === Foo; // true    

6.isPrototypeOf()

Array.prototype.isPrototypeOf([]) // true
Array.prototype.isPrototypeOf({}) // false

7.getPrototypeOf()

Object.getPrototypeOf([]) === Array.prototype // true

8.hasOwnProperty() 检测一个属性是存在于实例中,还是存在于原型中

Object.prototype.bar = 1; 
var foo = {goo: undefined};

foo.hasOwnProperty('bar'); // false
foo.hasOwnProperty('goo'); // true

原型链

原型链作为实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。每个对象都有一个指向它的原型对象的内部链接。这个原型对象又有自己的原型,直到某个对象的原型为 null 为止,组成这条链的最后一环,这种一级一级的链结构就称为原型链(prototype chain)。

var obj1 = {name:'one'};
obj2 = Object.create(obj1);
obj2.name = 'two';
console.log(obj1.name); // one

var obj1 = {prop:{name:'one'}};
obj2 = Object.create(obj1);
obj2.prop.name = 'two';
console.log(obj1.prop.name); // two

Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。


第一个

赋值前:

赋值后:

对象的属性是无法修改其原型链中的同名属性,而只会自身创建一个同名的属性并为其赋值,该属性将会屏蔽原型中的那个属性。

第二个

赋值前:

赋值后:

先计算 obj2.prop,在原型链中被发现,prop是个对象,所以这里存储的实际上是一个引用,也就是说,obj2找到了这个引用

参考资料:

JavaScript 高级程序设计 ch6
继承与原型链
JavaScript 秘密花园
JavaScript原型中的哲学思想