JavaScript 原型与原型链

 发布 : 2020-08-08  字数统计 : 624 字  阅读时长 : 2 分  分类 : JavaScript  浏览 :

基本概念

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念

  • 构造函数 Person
  • 原型对象 Person.prototype
  • 原型对象都包含一个指向构造函数的指针 constructor
  • 实例都包含一个指向原型对象的内部指针 person --- __proto__ > Person.prototype
  • 结果:Person.prototype === obejct ?
    => 由上推出条件一:Person.prototype.__proto__ == obejct.__proto__ ,条件二:object.__proto__ == Object.prototype
  • 从而推出 Person.prototype.__proto__ === Object.prototype

每一个对象都有 __proto__ 属性, 指向对应的构造函数的 prototype 属性.

class 为构造函数的语法糖, 数据类型是函数,类本身就指向构造函数。

图中由相互关联的原型 (__proto__) 组成的链状结构就是原型链,也就是由 __proto__ 连接的这条线.

类的实例对象

类的所有实例共享一个原型对象.

1
2
3
4
5
6
7
8
9
class Point {
}

let p1 = new Point();
let p2 = new Point();

p1.__proto__ === p2.__proto__ // true
p1.__proto__ === p2.__proto__ == Point.prototype //true
Point.__proto__ === Function.prototype // true

p1 p2 都为 Point 的实例,它们的原型 (p1.__proto__, p2.__proto__) 都等于 Point.prototype.

可以通过实例的 __proto__ 给类添加方法,且所有共享.

类的继承

class 为构造函数的语法糖. 同时有 prototype__proto__ 属性. 则存在两条继承链.

  • 子类的 __proto__ 属性表示构造函数的继承,总是指向父类.
  • 子类 prototype 属性的 __proto__ 属性表示方法的继承,总是指向父类的 prototype 属性
1
2
3
4
5
6
7
8
9
10
class Animal {

}

class Dog extends Animal {

}

Dog.__proto__ === Animal // true
Dog.prototype.__proto__ === Animal.prototype // true
  • 作为对象,子类(Dog)的 __proto__ 属性是父类(Animal)
  • 作为构造函数,子类(Dog)的 prototype 属性的 __proto__ 属性是父类的 prototype 属性

参考

留下足迹