Не могу переместить метод, который использует супер - PullRequest
0 голосов
/ 10 октября 2018

Я читаю эту книгу .Проверьте раздел "15.6.4.2 Подводный камень: Метод, который использует супер, не может быть перемещен "

В нем говорится следующее

Вы не можете переместитьметод, который использует super: у такого метода есть внутренний слот [[HomeObject]], который связывает его с объектом, в котором он был создан. Если вы переместите его с помощью присваивания, он продолжит ссылаться на суперсвойства исходного объекта.

Итак, я попытался вызвать его с другим объектом, а также назначить метод экземпляра для другого объекта, но, похоже, он не работает.Это относится к свойствам нового объекта.Возможно, я не правильно понял, что имеет в виду автор.Так, может кто-нибудь, пожалуйста, привести пример?

Hers - это small demo и код ниже

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

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Ваш код в порядке, потому что 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 }
);

Более подробные сведения объяснены в книге :

0 голосов
/ 10 октября 2018

OP говорит, что super.sayHi() всегда будет вызывать A.prototype.sayHi, независимо от того, какой объект вы вызываете методом.Можно было ожидать, что

const sayHi = new B().sayHi; // or B.prototype.sayHi

const prototype = {
  sayHi() {
    console.log("not the a property");
  }
};
const myObject = Object.assign(Object.create(prototype), {
  a: "the a property"
});
myObject.sayHi = sayHi;
myObject.sayHi();
// or just sayHi.call(myObject);

зарегистрирует не свойство a - вызвав prototype.sayHi через цепочку прототипов myObject.Но это не то, что происходит, оно регистрирует свойство a как нормальное.

...