JS类继承中,访问父类属性时this与super的差异是什么?
super与this访问父类成员的核心差异
你遇到的情况其实是原型链机制带来的结果:子类实例的原型链会指向父类的原型,所以this.mouse()会顺着原型链找到父类的mouse方法。但super和this在访问父类成员时,有几个关键差异:
1. 方法查找逻辑完全不同
如果子类重写了父类的同名方法,两者的行为会立刻分化:
super.mouse()会直接跳过子类的重写,调用父类原型上的原方法this.mouse()会优先调用子类自己的方法,只有子类没重写时才会找父类的
比如给Footballer加个重写的mouse方法:
class Footballer extends Human { mouse(sentense) { console.log(`${this.name} (${this.position}): "${sentense}".`); } talk(sentense) { super.mouse(sentense); // 调用Human的mouse this.mouse(sentense); // 调用Footballer自己的mouse } } const messi = new Footballer('Messi', 36, 'Forward', 'Inter Miami'); messi.talk('I love football'); // 输出: // Messi: "I love football". // Messi (Forward): "I love football".
2. 访问实例属性的本质不同
对于name、age这类实例属性:
this.name直接访问的是当前子类实例本身的属性——这些属性是父类构造函数通过super(name, age)执行时,挂载到当前实例上的super根本不能直接访问实例属性(比如写super.name会报错),它只能用来调用父类的原型方法,或者在构造函数里调用父类构造函数
3. 方法内部的this指向一致
不管用super.mouse()还是this.mouse(),方法内部的this都是指向当前的子类实例。这也是你例子里两者输出结果相同的原因——父类的mouse方法里的this.name,拿到的都是子类实例的name。
4. 使用场景有明确区分
- 当你必须调用父类的原始实现,不想被子类重写影响时,用
super.xxx() - 当你想遵循默认的原型链查找规则(子类有实现就用子类的,没有就 fallback 到父类),用
this.xxx()
内容的提问来源于stack exchange,提问作者user17620914
相关产品推荐
相关产品推荐

