返回

JavaScript原型与原型链的奥秘

前端

JavaScript 原型与原型链的奥秘:对象继承的秘密世界

何为原型?

想象一下原型对象就像一个模板,为同一类对象定义了一组共享的特征和行为。每个构造函数,也就是创建对象的工厂,都有一个指向其原型对象的 prototype 属性。

原型链的威力

原型链就是连接对象及其原型的链条。当我们访问对象的属性或方法时,JavaScript 沿原型链向上查找,直到找到所需的内容。这就像家庭树一样:孩子(对象)继承了父母(原型)的特征,而父母又继承了祖父母(更高级别的原型)的特征。

原型继承:对象间的传承

原型继承允许对象继承原型对象的属性和方法。这就好比一个孩子从父母那里遗传了某些特征。例如,一个 Student 构造函数可以从 Person 构造函数继承 nameage 属性,并添加一个新的 major 属性。

代码示例:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

function Student(name, age, major) {
  Person.call(this, name, age);
  this.major = major;
}

Object.setPrototypeOf(Student.prototype, Person.prototype);

const student = new Student('John', 20, 'Computer Science');
student.sayHello(); // "Hello, my name is John and I am 20 years old."

原型污染:小心意外继承

原型污染就像给家庭树添加了一个陌生人。向原型对象添加新的属性或方法会影响所有继承该原型的对象。要防止这种意外继承,我们可以使用 Object.freeze() 方法冻结原型对象。

代码示例:

Object.freeze(Person.prototype);

原型委托:另一种继承途径

原型委托提供了一种不同的继承机制,其中一个对象(委托对象)将属性或方法委托给另一个对象(委托目标对象)。这就好比一个孩子向叔叔或阿姨寻求指导。

代码示例:

const person = {
  name: 'John',
  age: 20
};

const student = {
  major: 'Computer Science'
};

Object.setPrototypeOf(student, person);
student.sayHello(); // "Hello, my name is John and I am 20 years old."

总结

原型和原型链是理解 JavaScript 对象继承的关键。通过原型继承,对象可以从其原型继承特征和行为。原型委托提供了一种替代的继承机制,而原型污染则是一种需要警惕的潜在陷阱。

常见问题解答

1. 什么是构造函数?

构造函数是创建对象的工厂。它定义了对象的属性和方法。

2. 如何检查对象的原型?

可以使用 Object.getPrototypeOf() 方法获取对象的原型。

3. 如何防止原型污染?

使用 Object.freeze() 方法冻结原型对象。

4. 原型继承和原型委托有什么区别?

原型继承使对象继承原型对象的属性和方法,而原型委托使对象委托其属性和方法给另一个对象。

5. JavaScript 中对象的继承方式有哪些?

JavaScript 中对象的继承方式有三种:原型继承、原型委托和类(ES6 中引入)。