原型与原型链

94 阅读2分钟

原型

我们创建的每一个函数都有一个 prototype 属性,这个属性是一个指针,指向一个对象,而这个对象就是原型对象。

这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。

当我们把一个函数当做构造函数,去new或实例化一个对象时,它就会把实例化出来的对象上的__proto__的属性指向这个原型对象,即将函数的prototype属性赋值给实例化对象的__proto__属性

原型又分为显式原型和隐式原型,显式原型是ECMA规定的,可以随便用,而隐式原型是浏览器为了方便我们实现的一个api,在实际项目中不要使用。

  1. 显示原型就是对象上的prototype属性
  2. 隐式原型就是对象上的__proto__属性

原型上有一个constructor属性,该属性指向prototype所在的函数对象上

这三者的关系如图所示:

在这里插入图片描述

console.log(Person.prototype === p.__proto__);  // true
console.log(Person.prototype.constructor === Person); // true
console.log(p.__proto__.constructor === Person); // true
...

原型链

当访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的__proto__里找这个属性,如果这个__proto__里也不存在这个属性,又因为__proto__指向了原型对象,而原型对象上也会有一个__proto__属性,那么这个原型对象就又会去自己的__proto__上找,于是就这样一直找下去,这样形成的链条就是原型链。

原型链的尽头一般来说都是 Object.prototype 所以这就是新建的对象为什么能够使用 toString() 等方法的原因。

而最后的原型,即Object.prototype.__proto__的值是null,这就意味着原型链的结束。

获取原型的方法

  • p.__proto__
  • p.constructor.prototype
  • Object.getPrototype(p) 在这里插入图片描述