面试题答案
一键面试类的定义和实例化过程中,原型链的构建与作用
- 类的定义:在 JavaScript 中,虽然 ES6 引入了
class
关键字,但本质上还是基于原型链的。当定义一个类时,其实是创建了一个函数(类的构造函数),并且会自动生成一个prototype
对象。例如:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name +'makes a sound.');
}
}
这里 Animal
是一个函数,Animal.prototype
有一个 constructor
属性指向 Animal
函数本身。
- 实例化过程:当使用
new
关键字创建类的实例时,新对象的[[Prototype]]
(可通过__proto__
访问)会被设置为类的prototype
对象。例如:
const dog = new Animal('Buddy');
dog.__proto__
指向 Animal.prototype
。这样当访问 dog
的属性或方法时,如果 dog
自身没有该属性或方法,就会沿着原型链向上查找,也就是到 Animal.prototype
中查找。如果 Animal.prototype
也没有,会继续向上查找它的原型(Object.prototype
),直到找到或者到达原型链顶端(null
)。
- 原型链的作用:它实现了对象之间的属性和方法继承。通过原型链,多个实例可以共享原型对象上的属性和方法,节省内存空间。例如所有
Animal
的实例都可以共享speak
方法,而不必在每个实例上都创建该方法。
实际应用场景
-
代码复用与优化:在开发框架或库时,通过原型链继承可以减少重复代码。比如 jQuery 库,它利用原型链为所有 jQuery 对象提供了一系列通用的方法,如
addClass
、removeClass
等。每个 jQuery 对象实例都可以通过原型链访问这些方法,而不需要在每个实例中重复定义,大大优化了代码体积和性能。 -
解决复杂问题 - 模拟多重继承:JavaScript 本身不支持多重继承,但通过原型链可以模拟。例如,一个对象可能需要从多个不同的“类”中获取属性和方法。可以通过将多个对象的原型依次添加到目标对象的原型链中来实现类似多重继承的效果。
function A() {}
A.prototype.aMethod = function() {
console.log('a method');
};
function B() {}
B.prototype.bMethod = function() {
console.log('b method');
};
function C() {}
// 模拟多重继承
C.prototype = Object.create(A.prototype);
Object.assign(C.prototype, B.prototype);
const c = new C();
c.aMethod();
c.bMethod();
在这个例子中,C
的实例可以访问 A
和 B
的方法,解决了类似多重继承的复杂问题。