一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
解释一下原型链
核心描述
-
原型:
- MDN 解释:JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。
- 红宝书(《JavaScript 高级程序设计(第4版)》,下同)解释:每个函数都会创建一个
prototype
属性,这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。这个对象就是通过调用构造函数创建的对象的原型。
-
原型链:
- MDN 解释:原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。
- 红宝书解释:每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。如果原型对象本身是另一个类型的实例,那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链,而原型链的对顶层指向了
Object.prototype
, 此原型对象的原型__proto__
为null
。
-
补充说明:
- 在 JavaScript 中,只要创建一个函数,就会按照特定的规则为这个函数创建一个
prototype
属性(指向原型对象)。默认情况下,所有原型对象自动获得一个名为constructor
的属性,指向与之关联的构造函数。 - 每次调用构造函数创建一个新实例时(如:new XXXFunction()),这个实例内部 [[Prototype]] 指针就会被赋值为构造函数的原型对象。脚本中没有访问这个 [[Prototype]] 特性的标准方式,但是常见的浏览器会在每个对象上暴露
__proto__
属性,通过这个属性可以访问对象的原型。
- 在 JavaScript 中,只要创建一个函数,就会按照特定的规则为这个函数创建一个
知识拓展
在 JavaScript 诞生之初,语言设计的作者 Brendan Eich 最开始选择了基于原型的编程,用于实现 JavaScript 的对象的继承。这门语言还参考了其他语言的一些特性。
-
借鉴C语言的基本语法;
-
借鉴Java语言的数据类型和内存管理;
-
借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位;
-
借鉴Self语言,使用基于原型(prototype)的继承机制。
-
基于构造器的继承
function Rectangle(width, height) { this.height = height; this.width = width; } Rectangle.prototype.area = function () { return this.width * this.height; }; var rect = new Rectangle(5, 10);
-
基于原型的继承
var square = Object.create(rectangle); square.create = function (side) { return rectangle.create.call(this, side, side); }; var sq = square.create(5);
-
基于类的继承(ES6以后支持)
class A {} class B extends A { } let bObj = new B()
参考资料
- 前端边角料 | 浅析 JavaScript 语言的原型与原型链:juejin.cn/editor/draf…
浏览知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。