原型与原型链

122 阅读2分钟

原型(prototype)

所有实例对象需要共享的属性和方法,都放在这个 prototype 对象里面;那些不需要共享的属性和方法,就放在构造函数里面。

实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。

  1. 每个对象都具有一个__ proto __ 属性,并且指向自身的构造函数的prototype。
  2. 每个构造函数都具有名为prototype的方法(构造函数标准为首字母大写,例如Function()Object()等以及自己创建的)。
  3. 调用构造函数的公式:var 对象实例 = new 构造函数()。

请参考阮一峰老师博客来理解继承:Javascript继承机制的设计思想

原型链(prototype chain)

对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

__ proto__ 和 prototype 的区别

  • 不能断章取义,__ proto__ 和 prototype 只是两个 key 而已
  • 我们一般研究对象的__ proto__和函数的prototype
  • 对象.__ proto__ === 某函数.prototype
  • 如果把函数看成对象,那么函数.__ proto__ === Function.prototype
  • 如果把 Function 看成对象,那么 Function.__ proto__ === Function.prototype

公式

var 对象 = new 函数() 
对象.__proto__ === 对象的构造函数.prototype

推论

var number = new Number()
number.__proto__ = Number.prototype

var object = new Object()
object.__proto__ = Object.prototype

var function = new Function()
function.__proto__ = Function.prototype

另外,所有函数都是由 Function 构造出来的,所以

Number.__proto__ = Function.prototype 
// 因为 Number 是函数,是 Function 的实例

Object.__proto__ = Function.prototype 
// 因为 Object 是函数,是 Function 的实例,Function 是 Object 的构造函数

Function.__proto__ == Function.prototye 
// 因为 Function 是函数,是 Function 的实例!