解释一下原型链

459 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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 诞生之初,语言设计的作者 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()
    

参考资料

浏览知识共享许可协议

本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。