原型链

prototype_chain_01

构造函数

使用构造函数创建一个实例对象。

function Person() {}
var person = new Person()
person.name = 'Trauma'
console.log(person.name) // Trauma

在这个例子中,Person 就是一个构造函数,我们使用 new 创建了一个实例对象 person

prototype

每个 构造函数 都有一个 prototype 属性,该属性指向构造函数创建的实例对象的原型对象。

function Person() {}
Person.prototype.name = 'Trauma'

var person1 = new Person()
var person2 = new Person()

console.log(person1.name) // Trauma
console.log(person2.name) // Trauma

那什么是原型对象呢?你可以这样理解:每一个 JS 对象 ( null 除外)在创建的时候就会与之关联另一个对象, 这个对象就是我们所说的原型对象,每一个对象都会从原型对象 "继承" 属性。

构造函数和实例原型对象之间的关系图如下:

prototype_01

__proto__

每个 实例对象 都有一个 __proto__ 属性,该属性指向实例对象的原型对象。

function Person() {}
var person = new Person()
console.log(person.__proto__ === Person.prototype) // true

更新下关系图:

prototype_02

constructor

每个 原型对象 都有一个 constructor 属性指向关联的构造函数。

function Person() {}
console.log(Person === Person.prototype.constructor) // true

更新下关系图:

prototype_03

实例与原型

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

function Person() {}

Person.prototype.name = 'Violet';

var person = new Person();

person.name = 'Trauma';
console.log(person.name) // Trauma

delete person.name;
console.log(person.name) // Violet

原型的原型

原型对象也是对象,既然是对象,我们就可以用最原始的方式创建它:

var obj = new Object();
obj.name = 'Trauma'
console.log(obj.name) // Trauma

更新下关系图:

prototype_04

原型链

原型链本质上就是查找属性或方法的链条。当访问一个属性或方法时,解释器首先会在当前对象中查找, 若没找到则会在对象的原型对象中继续查找,直到找到该属性或方法,或抵达最顶层的原型对象为止,这就是原型链。

prototype_05

prototype_chain_02

参考

Last Updated:
Contributors: Vsnoy