What does Function.prototype.toMethod() do?

后端 未结 2 564
一向
一向 2020-12-03 17:36

I noticed that the Function.prototype has a toMethod() method in experimental JavaScript, but what does that actually do? And how do I use it?

相关标签:
2条回答
  • 2020-12-03 18:11

    Update: the toMethod method was experimental only and did not make it into the standard. The home object is essentially static now, the only way to manipulate super is to change the [[prototype]]:

    var base = {…}; // as below
    var obj = Object.setPrototypeOf({
        foo() { // needs to use method definition syntax
           super.foo();
        }
    }, base);
    obj.foo();
    

    It's very similar to the bind method of function objects. However, instead of creating a new function with a bound this value, it creates a new function with a bound [[HomeObject]], which is the reference that is used for super calls:

    [[HomeObject]] (Object): If the function uses super, this is the object whose [[GetPrototypeOf]] provides the object where super property lookups begin.

    Consider this example (not using any class syntax):

    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
    
    0 讨论(0)
  • 2020-12-03 18:26

    My understanding is that .toMethod is like cloning a function. Consider the example in the source I posted,

    class P { }
    class C extends P {
        foo() {
            console.log("f");
            super();
        }
    }
    P.prototype.foo=C.prototype.foo;
    (new C).foo();
    

    Here you reference a subclass method .foo in the superclass, so when you call .foo, it will reference P's .foo which is C's .foo and you have just created a loop.

    It seems like to solve this issue, you can use .toMethod which "clones" the function and give it a different super/"home" that you specifed:

    P.prototype.foo = C.prototype.foo.toMethod(P.prototype);
    

    now calling (new C).foo() would not go on forever.

    0 讨论(0)
提交回复
热议问题