Ho notato che lo Function.prototype
ha un metodo toMethod()
in JavaScript sperimentale, ma cosa fa effettivamente? E come lo uso?Cosa fa Function.prototype.toMethod()?
risposta
Aggiornamento: il metodo toMethod
era solo sperimentale e non lo ha fatto nello standard. L'oggetto casa è essenzialmente statica ora, l'unico modo per manipolare super
è quello di cambiare la [[prototype]]:
var base = {…}; // as below
var obj = Object.setPrototypeOf({
foo() { // needs to use method definition syntax
super.foo();
}
}, base);
obj.foo();
E 'molto simile al metodo di oggetti funzione bind
. Tuttavia, invece di creare una nuova funzione con un valore associato this
, crea una nuova funzione con un balzo [[HomeObject]]
, che è il riferimento che viene utilizzato per super
chiamate:
[[HomeObject]]
(Object): If the function usessuper
, this is the object whose[[GetPrototypeOf]]
provides the object where super property lookups begin.
consideri questo esempio (non utilizzando qualsiasi classe sintassi):
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
Capisco come usare bind e che restituisca una nuova funzione con un contesto differente ma il ** [[HomeObject]] ** che non capisco –
ho ora ho aggiunto un esempio su come potrebbe essere usato 'super' – Bergi
Non ho dimestichezza con come funziona tutto questo, ma sembra che dovrebbe essere' obj.bar = obj.foo.toMethod (base); ', giusto? Non stai impostando '[[HomeObject]] su' base'? – JDB
mia comprensione è che .toMethod
è come la clonazione di una funzione. Si consideri l'esempio nella fonte che ho postato,
class P { }
class C extends P {
foo() {
console.log("f");
super();
}
}
P.prototype.foo=C.prototype.foo;
(new C).foo();
Qui si fa riferimento a un metodo di sottoclasse .foo
nella superclasse, in modo che quando si chiama .foo
, si farà riferimento P
's .foo
che è C
' s .foo
e basta creato un ciclo.
Sembra che per risolvere questo problema, è possibile utilizzare .toMethod
che "cloni" la funzione e dargli un diverso super
/"casa" che si specifed:
P.prototype.foo = C.prototype.foo.toMethod(P.prototype);
ora chiamando (new C).foo()
non sarebbe andare avanti per sempre.
ok c'è solo una cosa che non capisco e poi la prenderò. È ** super() ** che rappresenta la ** classe P ** –
Penso che ora il metodo sia di proprietà di P quindi 'super' non sarebbe affatto disponibile. . –
prima di chiamare ** ** toMethod questo è lo stesso in ES5: 'funzione P() {}' ' funzione C() {}' ' C.prototype = new P();' 'C.prototype.foo = function() { console.log ('f'); P(); } ' ' P.prototype.foo = C.prototype.foo; ' ' (nuovo C) .foo() ' –
Forse correlato: https://esdiscuss.org/topic/any-tomethod-use-case#content-1 –
Non ho mai fatto alcun mix o composizione di classe quando si tratta di ereditarietà. quindi non capisco ancora di cosa stiano parlando o come usarlo –
@Edwin - Non penso che sia pensato per essere utilizzato dallo sviluppatore JavaScript casuale. È una funzione di livello molto profondo da utilizzare nelle librerie JavaScript avanzate che dipendono da alcune caratteristiche dell'ereditarietà dei prototipi che sono anche in stato "sperimentale" (come la funzione "' super() '") – JDB