首页 > 解决方案 > 无法移动使用 super 的方法

问题描述

我正在读这本书。检查部分“15.6.4.2 陷阱:使用 super 的方法无法移动

它说明了以下内容

你不能移动使用 super 的方法:这样的方法有一个内部槽 [[HomeObject]] 将它绑定到创建它的对象。如果你通过赋值移动它,它将继续引用超属性的原始对象。

所以,我尝试用不同的对象调用它,也将实例方法分配给不同的对象,但它似乎不起作用。它指的是新对象的属性。大概,作者的意思我没听懂。那么,有人可以举个例子吗?

Hers 是一个小演示,代码如下

class A {
  get a() {
    return 1;
  }

  sayHi() {
    console.log(this.a)
  }
}

class B extends A {
  sayHi() {
    super.sayHi();
  };
}
var obj = {
  a: 4
};
let b = new B();
b.sayHi();
// logs 1

b.sayHi.call(obj);
// logs 4

obj.sayHi = b.sayHi;
obj.sayHi();
// logs 4

标签: javascriptecmascript-6es6-class

解决方案


您的代码没问题,因为this在您移动方法时有效,但super无效(并且您的代码仅真正测试this)。以下代码测试super

class Bird {
  getName() {
    return 'Bird';
  }
}
class Mammal {
  getName() {
    return 'Mammal';
  }
}
class Human extends Mammal {
  getName() {
    return super.getName();
  }
}
class Duck extends Bird {
}
// Moving method .getName() from Human.prototype to Duck.prototype
Duck.prototype.getName = Human.prototype.getName;

console.log(new Duck().getName()); // 'Mammal' (not 'Bird')

要了解结果,您需要了解其super工作原理——它使用存储在方法本身中的内部属性[[HomeObject]],它不依赖于this. 也就是说,Human.prototype.getName()内部工作如下:

Human.prototype.getName = Object.assign(
  function me() {
    return me.__HomeObject__.__proto__.getName();
  },
  { __HomeObject__: Human.prototype }
);

书中解释了更多细节:


推荐阅读