JavaScript原型与原型链的奥秘
2023-10-27 07:22:31
JavaScript 原型与原型链的奥秘:对象继承的秘密世界
何为原型?
想象一下原型对象就像一个模板,为同一类对象定义了一组共享的特征和行为。每个构造函数,也就是创建对象的工厂,都有一个指向其原型对象的 prototype
属性。
原型链的威力
原型链就是连接对象及其原型的链条。当我们访问对象的属性或方法时,JavaScript 沿原型链向上查找,直到找到所需的内容。这就像家庭树一样:孩子(对象)继承了父母(原型)的特征,而父母又继承了祖父母(更高级别的原型)的特征。
原型继承:对象间的传承
原型继承允许对象继承原型对象的属性和方法。这就好比一个孩子从父母那里遗传了某些特征。例如,一个 Student
构造函数可以从 Person
构造函数继承 name
和 age
属性,并添加一个新的 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 中引入)。