什么是 JavaScript 中的原型链?

JavaScript 中的原型链是一种用于实现对象继承的核心机制,通过链接 prototype 对象形成链式结构。

JavaScript 中等 面向对象编程 原型链 面向对象

原型链 ( Prototype Chain ) 是 JavaScript 中实现对象继承的核心机制,基于对象之间的链接(原型对象)形成一个链式结构。当访问一个对象属性或方法时,若该对象自身未定义, JavaScript 引擎会沿原型链逐级向上查找,直到找到属性或到达链末端 ( null )。

以下是详细解释:

  • 定义与基本概念
    JavaScript 中每个对象都有内部属性 ( [[Prototype]] ),指向其原型对象。原型本身也是一个对象,可能拥有自己的原型,构成一条“原型链”,终结点为 null。此机制支持继承和属性共享,使 JavaScript 成为基于原型的语言。
  • 工作原理
    1. 属性查找流程:访问属性时先在对象自身搜索;如未找到,沿着其原型链查找上级原型对象 ( 例如通过 __proto__Object.getPrototypeOf() 获取的链接 ),递归向上直至找到属性或抵达 null ( 此时返回 undefined )。
    2. 作用范围:如方法访问或属性查询都遵循此过程,确保动态性,例如自定义方法通过原型链覆盖原生方法。
  • 函数的角色与示例
    构造函数定义了 .prototype 对象,包含所有实例共享的属性和方法。通过 new 创建对象时,其实例的 __proto__ 指向构造函数的 .prototype,完成继承。
    例如:

    function Person(name) {
      this.name = name; // 实例属性
    }
    Person.prototype.greet = function() { // 共享方法
      console.log("Hello, I am " + this.name);
    };
      
    const person = new Person("Alice");
    console.log(person.hasOwnProperty("name")); // true
    console.log(person.hasOwnProperty("greet")); // false, 方法不在对象上, 来自 Person.prototype
    console.log(person.greet()); // Hello, I am Alice
    

    在上面代码中,person.greet() 成功调用是因为沿着链查找: personPerson.prototypeObject.prototype。若无此机制,会无法调用不存在的属性。

  • 继承实现
    • 设置子类型构造函数的 .prototype 为父类型实例,如 ES5: Child.prototype = Object.create(Parent.prototype);
    • 在 ES6 中使用 class 语法简化但底层依然基于原型链:
    class Animal {
      constructor(species) {
        this.species = species;
      }
      describe() {
        console.log("Species: " + this.species);
      }
    }
      
    class Dog extends Animal {
      constructor(name) {
        super("Dog"); // 调用父构造函数
        this.name = name;
      }
    }
      
    const dog = new Dog("Buddy");
    dog.describe(); // Species: Dog, 通过原型链找到 Animal.prototype.describe
    
  • 重要性
    原型链提升代码复用率和性能:
    • 避免冗余方法定义在构造函数中,节省内存。
    • 实现动态和灵活继承方式 ( 如原型链共享更改会反映在所有实例 )。
  • 潜在问题与注意
    使用非标准 __proto__ 不推荐 ( 可使用 Object.getPrototypeOf() / Object.setPrototypeOf() )。过度修改原型链可能导致逻辑错误。

此机制是 JavaScript 基础组成部分,帮助理解语言本质如封装、继承和多态。