Function.prototype.toMethod() 有什么作用?

IT技术 javascript ecmascript-6
2021-03-15 07:00:54

我注意到实验性 JavaScript 中Function.prototype有一个toMethod()方法,但这实际上是做什么的?我该如何使用它?

2个回答

更新:该toMethod方法只是实验性的,并未纳入标准。home 对象现在基本上是静态的,唯一的操作方法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]](Object):如果函数使用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
我了解如何使用 bind 并且它返回一个具有不同上下文的新函数但是我不明白[[HomeObject]]
2021-04-22 07:00:54
@JDB:不,我正在设置[[HomeObject]]to obj,因为super基本上意味着GetPrototypeOf([[HomeObject]])
2021-04-27 07:00:54
啊...所以要让 foo 在没有引用错误的情况下工作,你会使用obj.foo = (function(){super.foo()}).toMethod(obj);或者这会导致无限循环吗?
2021-05-05 07:00:54
我现在添加了一个关于如何super使用的示例
2021-05-10 07:00:54
我不熟悉这一切是如何运作的,但似乎应该如此obj.bar = obj.foo.toMethod(base);,对吧?你不是设置[[HomeObject]]base吗?
2021-05-16 07:00:54

我的理解是这.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 .foowhich is C's.foo并且您刚刚创建了一个循环。

似乎要解决这个问题,您可以使用.toMethodwhich "clone" 函数并为其指定一个不同的super/"home":

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

现在呼叫(new C).foo()不会永远持续下去。

在调用.toMethod之前在es5 中 是一样的:function P(){} function C(){} C.prototype = new P(); C.prototype.foo = function(){ console.log('f'); P(); } P.prototype.foo = C.prototype.foo; (new C).foo()
2021-04-21 07:00:54
我现在已经研究了半个小时的草稿,得出的结论是,您需要做super.foo()而不仅仅是super()- 这仅适用于从其他函数继承的(构造函数)函数。任何人都可以确认(测试?)这一点吗?
2021-04-23 07:00:54
好的,只有一件事我不明白,然后我会明白的。代表类Psuper()
2021-04-24 07:00:54
我认为现在该方法属于 P 所以super根本不可用。
2021-04-24 07:00:54
@Bergi:我知道这是旧的,你可能知道答案,但仅供参考:AFAIKsuper() 曾经在每个方法中都有效,它只会调用父方法。但是规范最近发生了变化,super()现在只允许在构造函数super.method()中确实是在重写方法中调用父方法的方式。
2021-05-07 07:00:54