在 javascript 中,使用 class 箭头函数字段实现继承的核心做法是:在子类构造函数中调用 super() 以初始化父类实例,随后通过 this 直接定义箭头函数属性。由于箭头函数没有自己的 this,它们会捕获定义时的词法作用域(即子类实例),从而避免传统方法需要手动绑定 this 的问题。

如何定义包含箭头函数的子类并正确继承父类状态?
要定义一个包含箭头函数的子类,必须在子类的构造函数第一行调用 super(),确保父类的属性和方法被正确挂载到当前实例上。之后,直接在类体中声明箭头函数即可。这些箭头函数将自动绑定到子类实例,能够访问父类通过 super 暴露的属性和方法。

class Parent {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, I am ${this.name}`;
}
}
class Child extends Parent {
constructor(name, age) {
super(name);
this.age = age;
// 箭头函数字段,this 指向 Child 实例
this.getDetails = () => {
return `${this.greet()}, I am ${this.age} years old`;
};
}
}
const child = new Child('Alice', 5);
console.log(child.getDetails()); // "Hello, I am Alice, I am 5 years old"
console.log(child instanceof Parent); // true
console.log(child instanceof Child); // true
上述代码中,Child 继承了 Parent。super(name) 调用了父类构造函数,设置了 this.name。然后定义了 this.getDetails 箭头函数。当调用 child.getDetails() 时,箭头函数内部的 this 指向 child 实例,因此可以成功调用 this.greet() 和访问 this.age。结果字符串为 "Hello, I am Alice, I am 5 years old"。
立即学习“Java免费学习笔记(深入)”;
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。
箭头函数字段与原型方法在继承中的行为差异是什么?
箭头函数字段作为实例属性存在,而原型方法是共享的。这意味着每个子类实例都会拥有自己独立的箭头函数副本,但所有实例共享原型上的方法。在继承场景中,这影响了内存使用和 this 绑定的方式。箭头函数在定义时捕获 this,而原型方法需要在调用时确定 this,通常通过实例调用或显式绑定。

class Parent {
constructor(value) {
this.value = value;
}
// 原型方法
getValue() {
return this.value;
}
}
class Child extends Parent {
constructor(value) {
super(value);
// 箭头函数字段
this.getValueArrow = () => {
return this.value;
};
}
}
const child1 = new Child(10);
const child2 = new Child(20);
// 原型方法共享
console.log(Parent.prototype.getValue === Child.prototype.getValue); // false (Child 未覆盖)
console.log(Object.getPrototypeOf(child1).getValue === Object.getPrototypeOf(child2).getValue); // true (如果 Child 没定义原型方法,则继承自 Parent)
// 箭头函数不共享
console.log(child1.getValueArrow === child2.getValueArrow); // false
// 调用结果
console.log(child1.getValue()); // 10
console.log(child1.getValueArrow()); // 10
console.log(child2.getValue()); // 20
console.log(child2.getValueArrow()); // 20
在这个例子中,Child 继承了 Parent。getValue 是原型方法,存储在 Parent.prototype 上。由于 Child 没有定义同名的原型方法,child1 和 child2 都使用 Parent.prototype.getValue。当通过实例调用时,this 分别指向 child1 和 child2,返回各自的 value。getValueArrow 是箭头函数字段,每个实例创建时都会生成一个新的函数对象,因此 child1.getValueArrow 和 child2.getValueArrow 是不同的函数引用。但它们都捕获了各自实例的 this,所以也能正确返回各自的 value。主要区别在于内存占用:getValueArrow 每个实例都有副本,而 getValue 是共享的。
如果在子类中重新定义父类的同名箭头函数会发生什么?
如果在子类中重新定义与父类实例属性同名的箭头函数,子类的版本会覆盖父类的版本。这是因为属性赋值是按顺序执行的,子类构造函数中的赋值会修改实例上的属性。如果父类也定义了同名箭头函数,它会在 super() 调用后被子类的新定义覆盖。这种行为类似于普通属性的覆盖,但需要注意箭头函数的词法 this 绑定是在定义时确定的。
class Parent {
constructor() {
this.getMessage = () => 'Parent Message';
}
}
class Child extends Parent {
constructor() {
super();
this.getMessage = () => 'Child Message';
}
}
const child = new Child();
console.log(child.getMessage()); // "Child Message"
在 Child 的构造函数中,首先调用 super(),这会执行 Parent 的构造函数,在实例上设置 this.getMessage 为一个返回 "Parent Message" 的箭头函数。接着,执行 this.getMessage = () => 'Child Message',这会覆盖之前的 this.getMessage。因此,最终 child.getMessage 是一个返回 "Child Message" 的箭头函数。调用 child.getMessage() 输出 "Child Message"。这展示了子类如何覆盖父类定义的实例属性,包括箭头函数。

















