参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
https://zh.javascript.info/native-prototypes
javascript是基于原型的,当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象( object )都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( __proto__ ) ,层层向上直到一个对象的原型对象为 null
。根据定义,null
没有原型,并作为这个原型链中的最后一个环节。
先说说__proto__属性和prototype属性:
__proto__对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型。
prototype原型属性,这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数
可以通过__proto__属性或Object.getPrototypeOf访问器得到对象的原型。
来看看MDN上怎么说函数的原型:
一个空的function有constructor和__proto__,构造函数的prototype属性与它创建的实例对象的[[prototype]]或__proto__属性指向的是同一个对象:
当对象继承另一个对象时,如下图,a对象继承自b,是b的原型,a上的属性和访问器都会继承到b.__proto__。:
数组和函数都是继承自object的原型:
Array对象继承自 Array.prototype 属性,Array.prototype
属性表示 Array
构造函数的原型,并允许向所有Array对象添加新的属性和方法。
Function.prototype
属性存储了 Function
的原型对象。,Function对象继承自 Function.prototype 属性。因此,Function.prototype 不能被修改。
最后Object.prototype的原型继承自null:
在原型链上查找属性比较耗时,试图查找不存在的属性时,会遍历整个原型链。
看到这里,请问,下面两段脚本会输出什么?
第二段脚本,a.a()是不存在,Function.prototype.a不生效的原因是,a.__proto__ = A.prototype,a.__proto__.__proto__ = A.prototype.__proto__ = Object.prototype,所以Function.prototype.a不在a的原型链上。