Javascript原型和原型链

原 型

平时我们常常这样定义一个构造函数:

function Animal(name) {
  this.name = name
}
Animal.prototype.eat = function() {
  console.log(this.name + ' is eating')
}
Animal.prototype.run = function() {
  console.log(this.name + ' is running')
}
const dog = new Animal('dog')
dog.eat() // 'dog is eating'
const cat = new Animal('cat')
cat.run() // 'cat is running'

在JavaScript中,每个函数有拥有一个prototype属性,指向这个函数的原型对象,原型对象的属性和方法会被构造函数的实例所继承。上例中Animal.prototype就是指向Animal的原型,原型方法eatrun会被dogcat所继承。
我们知道JavaScript中:
实例都有constructor属性,指向它的构造函数:dog.constructor === Animal
函数的原型对象的constructor又指向该函数自身:Animal.prototype.constructor === Animal
另外,JavaScript对象都拥有一个__proto__属性,它指向该对象的构造函数的原型对象:dog.__proto__ === Animal.prototype

原型链

试想:既然对象都有__proto__属性,那么函数的原型对象的__proto__属性指向谁呢?我们可以通过构造函数的名字来得到答案:

Animal.prototype.__proto__.constructor.name // 'Object'

它指向一个对象,那么这个对象的__proto__又指向谁呢?我们继续:

Animal.prototype.__proto__.__proto__.constructor.name // 报错了
Animal.prototype.__proto__.__proto__ // 结果是null了

我们发现object再往上查看原型,就得到null了,上面这些不断向上查找原型的过程,就得到了js原型链。

扩 展

我们知道JavaScript中所有的数据类型都是继承自Object的,我们可以根据以上内容来验证。

[].__proto__.constructor.name; // 'Array'
[].__proto__.__proto__.constructor.name; // 'Object'
''.__proto__.constructor.name; // 'String'
''.__proto__.__proto__.constructor.name; // 'Object'
Function.prototype.__proto__.constructor.name; // 'Object'
Object.prototype.__proto__ // null

熟话说:“一切皆对象”,原来null才是最后赢家,因为typeof null === 'object'

你可能感兴趣的:(Javascript原型和原型链)