类的实现,与原型和原型链的关系
在 JavaScript 中,类的实现本质上是基于原型(Prototype)和原型链(Prototype Chain)的语法糖。虽然 ES6 引入了 class 关键字,但其底层仍然是原型继承的机制。以下是详细解析:
一、原型(Prototype)和原型链(Prototype Chain)
1. 原型(Prototype)
- 每个 JavaScript 对象都有一个隐藏的 
[[Prototype]]属性(可通过__proto__访问,但建议使用Object.getPrototypeOf())。 - 构造函数(Constructor) 的 
prototype属性指向一个对象,该对象会成为其实例的原型。 - 实例会继承原型对象上的属性和方法。
 
function Person(name) {
  this.name = name;
}
// 方法定义在构造函数的原型上
Person.prototype.sayHello = function() {
  console.log(`Hello, I'm ${this.name}`);
};
const alice = new Person("Alice");
alice.sayHello(); // 调用原型上的方法
2. 原型链(Prototype Chain)
- 当访问对象的属性或方法时,如果对象自身没有定义,会沿着原型链向上查找。
 - 原型链的终点是 
Object.prototype(其[[Prototype]]为null)。 
console.log(alice.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null
二、ES6 类的实现
ES6 的 class 语法是原型继承的语法糖,其底层逻辑与传统构造函数一致,但更清晰易读。
1. 基本类定义
class Person {
  constructor(name) {
    this.name = name;
  }
  sayHello() {
    console.log(`Hello, I'm ${this.name}`);
  }
}
const bob = new Person("Bob");
bob.sayHello();
2. 类的本质
class中的方法会被添加到构造函数的原型(Person.prototype)上。- 类的 
constructor对应传统构造函数。 
console.log(typeof Person); // "function"(类本质是函数)
console.log(Person === Person.prototype.constructor); // true
console.log(bob.__proto__ === Person.prototype); // true
三、继承与原型链
1. 通过 extends 实现继承
class Student extends Person {
  constructor(name, grade) {
    super(name); // 调用父类构造函数
    this.grade = grade;
  }
  study() {
    console.log(`${this.name} is studying in grade ${this.grade}`);
  }
}
const carol = new Student("Carol", 5);
carol.sayHello(); // 继承自 Person
carol.study();    // 自身方法
2. 继承的原型链
- 子类的原型(
Student.prototype)的[[Prototype]]指向父类的原型(Person.prototype)。 - 实例的 
[[Prototype]]指向子类的原型。 
console.log(Student.prototype.__proto__ === Person.prototype); // true
console.log(carol.__proto__ === Student.prototype); // true
console.log(carol.__proto__.__proto__ === Person.prototype); // true
四、类与原型的关系总结
| 特性 | 传统构造函数 | ES6 类 | 
|---|---|---|
| 构造函数 | function Person() {} | 
class Person { constructor() {} } | 
| 方法定义 | Person.prototype.method | 
直接在类中声明方法 | 
| 继承 | 手动设置原型链 | extends 和 super 自动处理 | 
| 静态方法 | Person.staticMethod | 
static staticMethod() {} | 
五、关键点与注意事项
- 
类的静态方法
通过static定义,属于类本身而非实例。class MathUtils { static add(a, b) { return a + b; } } console.log(MathUtils.add(1, 2)); // 3 - 
箭头函数与
this绑定
类中箭头函数会绑定到实例,而非原型。class Counter { count = 0; increment = () => { this.count++; }; // 箭头函数绑定到实例 } - 
原型方法的共享性
所有实例共享原型上的方法,避免在原型上定义可变状态。Person.prototype.age = 30; // 所有实例共享此属性(通常不推荐) - 
检查原型关系
使用instanceof或Object.getPrototypeOf()。console.log(carol instanceof Student); // true console.log(carol instanceof Person); // true 
六、总结
- 类的本质:ES6 类的底层实现基于原型链,
class是更优雅的语法糖。 - 继承机制:通过 
extends和super简化原型链的继承逻辑。 - 设计原则:优先使用类语法,但需理解其原型本质,尤其在处理 
this、继承和方法共享时。 
理解原型和原型链是掌握 JavaScript 面向对象编程的核心,类的语法让代码更符合直觉,但底层机制依然依赖原型系统。
                    
                
                
            
        
浙公网安备 33010602011771号