一张图彻底理解prototype与__proto__

239 阅读1分钟

what prototype?

如下demo,构造函数Cat的prototype对象,就是实例对象cat1和cat2的原型对象。在原型对象上添加一个color属性。结果,实例对象都能读取该属性。如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。

function Cat (name) {
  this.name = name;
}

Cat.prototype.color = 'white';

var cat1 = new Cat('Tom');
var cat2 = new Cat('Mark');

cat1.color // 'white'
cat1.name // 'Tom'
cat2.color // 'white'
cat2.color // 'Mark'

cat1.color = 'black';

cat1.color // 'black'
cat2.color // 'white'

原型链

__proto__(隐式原型)与prototype(显式原型)

访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着proto这条链向上找,这条链便是原型链

所有对象都有__proto__,而只有函数对象才有prototype。函数是一个特殊的对象,当一个函数被创建后,这个函数就会自动附带一个属性prototype,prototype它也是一个Object对象,代表着函数的原型。也就是说prototype就是原型对象,原型对象中包含两个属性:constructor和__proto__。constructor这个属性是指创建原型的函数,它指向函数本身,而__proto__指向原型对象。

JavaScript的每个对象都继承另一个对象,后者称为“原型”(prototype)对象。只有null除外,它没有自己的原型对象。原型对象上的所有属性和方法,都能被派生对象共享。这就是JavaScript继承机制的基本设计。

开篇的图,自下至上,来推:

function Cat (){}
let Tom = new Cat();

Tom.prototype
Tom.__proto__ === Cat.prototype

Cat.prototype.__proto__ === Object.prototype
Cat.prototype.constructor === Cat
Cat.__proto__ === Function.prototype

Function.constructor === Function
Function.__proto__ === Function.prototype
Function.prototype.__proto__ === Object.prototype

Object.constructor = Object
Object.__proto__ === Function.prototype
Object.prototype.__proto__ === null

结果如下:

总结

  • 所有的对象都有__proto__(null除外)
  • 只有function对象都有prototype
  • function是特殊的Object,所以function既有__proto__又有prototype