面试题答案
一键面试1. 通过原型链实现子类继承
具体方法
function Parent() {
this.name = 'parent';
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child() {
this.age = 10;
}
// 将Child的原型指向Parent的实例,这样Child的实例就可以访问Parent原型上的属性和方法
Child.prototype = new Parent();
Child.prototype.constructor = Child; // 修正构造函数指向
let child = new Child();
child.sayName(); // 输出 'parent'
继承属性和方法
- 继承属性:实例可访问父类原型上的属性,但无法直接访问父类实例属性。
- 继承方法:子类实例可以继承父类原型上的方法,方法定义在父类原型上,所有子类实例共享这些方法。
原型链结构
Child的原型是Parent的实例,Child实例的__proto__
指向Child的原型(即Parent的实例),Parent实例的__proto__
指向Parent的原型,形成一条原型链。
2. 通过构造函数借用实现子类继承
具体方法
function Parent(name) {
this.name = name;
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child(name, age) {
Parent.call(this, name); // 在Child构造函数中调用Parent构造函数,将Parent的属性绑定到Child实例上
this.age = age;
}
// Child.prototype = Object.create(Parent.prototype); // 可选择性添加,以便访问父类原型方法
// Child.prototype.constructor = Child;
let child = new Child('childName', 10);
// child.sayName(); // 如果没有设置Child.prototype = Object.create(Parent.prototype),此行会报错
继承属性和方法
- 继承属性:子类实例可以拥有与父类实例相同的属性,因为在子类构造函数中调用了父类构造函数,将父类属性绑定到了子类实例上。
- 继承方法:默认情况下,子类实例无法访问父类原型上的方法,除非手动设置
Child.prototype = Object.create(Parent.prototype)
。
原型链结构
Child的原型与Parent的原型没有直接联系(若不手动设置Child.prototype = Object.create(Parent.prototype)
),Child实例的__proto__
指向Child的原型,而不是Parent的实例或原型。
3. 通过ES6 class关键字实现子类继承
具体方法
class Parent {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Child extends Parent {
constructor(name, age) {
super(name); // 调用父类构造函数,初始化继承的属性
this.age = age;
}
}
let child = new Child('childName', 10);
child.sayName(); // 输出 'childName'
继承属性和方法
- 继承属性:子类通过
super
关键字调用父类构造函数来继承父类的属性,子类实例拥有父类实例的属性。 - 继承方法:子类可以继承父类的方法,并且可以重写父类方法。如果子类定义了与父类相同的方法,会覆盖父类方法。
原型链结构
ES6 class本质上还是基于原型链的,Child
的原型是Parent
原型的一个实例,Child
实例的__proto__
指向Child
的原型,Child
原型的__proto__
指向Parent
的原型,形成原型链。
区别总结
- 继承属性:
- 原型链继承:无法直接继承父类实例属性,只能访问父类原型属性。
- 构造函数借用:可继承父类实例属性,但默认无法访问父类原型方法(需额外设置)。
- ES6 class继承:通过
super
调用父类构造函数继承属性,可直接访问父类实例和原型属性及方法。
- 继承方法:
- 原型链继承:共享父类原型方法。
- 构造函数借用:默认无法继承,需手动设置原型关系。
- ES6 class继承:可继承并可重写父类方法。
- 原型链结构:
- 原型链继承:子类原型是父类实例,形成原型链。
- 构造函数借用:默认情况下子类原型与父类原型无直接联系(不手动设置时)。
- ES6 class继承:基于原型链,子类原型是父类原型的实例,形成原型链。