Что делает 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() не будет продолжаться вечно.

Другие вопросы по тегам