Что делает Function.prototype.toMethod()?
Я заметил, что Function.prototype
имеет toMethod()
метод в экспериментальном JavaScript, но что это на самом деле делает? И как мне это использовать?
2 ответа
Обновление: toMethod
Метод был только экспериментальным и не вошел в стандарт. Домашний объект теперь по сути статичен, единственный способ манипулировать super
это изменить [[prototype]]:
var base = {…}; // as below
var obj = Object.setPrototypeOf({
foo() { // needs to use method definition syntax
super.foo();
}
}, base);
obj.foo();
Это очень похоже на bind
метод функциональных объектов. Однако вместо создания новой функции с привязкой this
значение, оно создает новую функцию с привязкой [[HomeObject]]
, который является ссылкой, которая используется для super
звонки:
[[HomeObject]]
(Объект): если функция используетsuper
это объект которого[[GetPrototypeOf]]
предоставляет объект, с которого начинаются поиски супер-свойств.
Рассмотрим этот пример (без использования синтаксиса классов):
var base = {
foo: function() {
console.log("base foo called on", this);
}
};
base.foo(); // base foo called on base
var obj = Object.create(base);
obj.foo(); // base foo called on obj
obj.foo = function() {
super.foo();
};
obj.foo(); // ReferenceError: this method has no home
obj.bar = obj.foo.toMethod(obj);
obj.bar(); // base foo called on obj
obj.baz = function() {
super();
};
obj.baz(); // ReferenceError: this constructor has no parent class
Reflect.setPrototypeOf(obj.baz, base.foo);
obj.baz(); // base foo called on obj
Я понимаю, что .toMethod
это как клонирование функции. Рассмотрим пример из источника, который я разместил,
class P { }
class C extends P {
foo() {
console.log("f");
super();
}
}
P.prototype.foo=C.prototype.foo;
(new C).foo();
Здесь вы ссылаетесь на метод подкласса .foo
в суперклассе, поэтому, когда вы звоните .foo
будет ссылка P
"s .foo
который C
"s .foo
и вы только что создали цикл.
Кажется, чтобы решить эту проблему, вы можете использовать .toMethod
который "клонирует" функцию и дает ей другое super
/"дом", который вы указали:
P.prototype.foo = C.prototype.foo.toMethod(P.prototype);
сейчас звоню (new C).foo()
не будет продолжаться вечно.