每个对象,不管是对象直接量、还是构造函数创建的对象,都与另外一个对象关联,这个对象就是我们所说的原型。这里有两个重要的、容易混淆的项:__proto__和prototype。
(1)__proto__:是指向父构造器prototype的引用,称原型属性,就是我们所说的原型。所有实例对象都具有__proto__。
(2)prototype:称原型对象,子类就是从父类的prorotype继承属性,或者实例对象从对应的构造器上继承属性。所有构造器都具有prototype,用于被子构造器或者由他生成的实例对象继承。
设N1、N2、N3是构造器,n3是N3的实例对象,其中N1的父构造器是Object,N1是N2的父亲、N2是N3的父亲,则满足以下:
n3.__proto__ === N3.prototype
N3.prototype.__proto__ === N2.prototype
N2.prototype.__proto__ === N1.prototype
N1.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null
复制代码
简单来说,所有对象实例都会通过__proto__去继承父构造器的prototype上的属性,所有构造器若存在父构造器,都会继承父构造器的prototype上属性,以此类推,直至最终Object.prototype。而非prototype上的属性是不会被继承的。以上这种链式继承结构成为原型链。
如何实例化一个对象?
实例对象是通过构造器的constructor构造的,而任意构造器N满足:
N.prototype.constructor = N
复制代码
因此实例化一个n可以:
let n = new N()
或者
let n = new N.prototype.constructor()
复制代码
由于根据原型链知:n.__proto__ === N.prototype,因此在已知已有实例n的情况下,可以通过以下方式去实例化一个实例n_,效果等同于上述的实例化方法。
let n_ = new n.__proto__.contructor()
复制代码
简单描述继承关系
为方便理解,给出以下定义:
(1)从构造器继承而来的属性称继承属性
(2)实例或者构造器在自身prototype内定义的属性,称其自有prototype属性(或prototype属性)
(3)实例或者构造器定义的非prototype属性称自有属性
let obj = new Object()
// 设置Object的自有属性
Object.some_property = 'some_property'
Object.some_property === 'some_property' //true
// 设置Object的prototype属性,结果覆盖其自有属性,返回其自有prototype属性
Object.prototype.some_property = 'some_property_of_prototype'
Object.some_property === 'some_property_of_prototype' //true
//*1* 实例不能继承构造器自有属性,继承了其自有prototype属性**
//*2* 实例生成后,即使更改构造器的自有prototype属性内容,只要实例
// 没有覆盖这个属性,它获取属性值是个原型链追溯的过程,最终值会与
// 目标构造器prototype属性值保持一致
obj.some_property === 'some_property_of_prototype' //true
//*3* 实例覆盖继承属性,生成自有属性some_property
obj.some_property = 'some_property_of_self'
obj.some_property === 'some_property_of_self' //true
//*4* 删除自有属性,属性值仍从构造器property属性继承
delete obj.some_property
obj.some_property === 'some_property_of_prototype' //true
//*5* 删除构造器自有property属性,实例的属性为undefined
delete Object.Object.some_property
obj.some_property === undefined //true
复制代码
总结
-
每个构造器都可以自定义属性,包括自有属性和自有prototype属性,其中prototype属性是可以被子类或者实例继承。
-
查找任一实例o的属性x,会从实例自身的自有属性——>构造器自有属性——>构造器自有prototype属性——>...根据原型链依次查找祖先构造器的自有属性、自有prototype属性...——>Object自有属性、自有prototype属性依次遍历,中间一旦找到匹配项,便立即结束查找,返回结果。
-
任意构造器O查找属性x,会从构造器自有属性——>构造器自有prototype属性——>...根据原型链依次查找祖先构造器的自有属性、自有prototype属性...——>Object自有属性、自有prototype属性依次遍历,中间一旦找到匹配项,便立即结束查找,返回结果。