我知道如果你有一些javascript函数,并且你想调用它,那么在其中使用this
将不会引用直接调用它的对象,你可以使用func.call(thatObject,param,and,more,params...)
。< / p>
但假设您是func
的作者,而func的唯一用法是通过func.call,
你为什么不把它定义为:
function func(that,param,and,more,params...) {
//and in here use *that* and not *this*
}
是的,它看起来不那么“酷”,因为它不是一个物体的方法, 但是,如果func的唯一用法是通过func.call,那么它似乎只是额外的代码和开销。
我在这里遗漏了什么吗?或者我看到这种模式的源代码只是“OOed”?
答案 0 :(得分:2)
似乎存在很大的性能差异。使用
func(){
//code here, this.something
}
func.call(thatObject)
根据前几次测试,比使用
慢约8倍func(that){
//code here, that.something
}
func(thatObject)
亲自测试,JSPerf here
最终,速度本身并不是我们使用的代码最重要的因素。代码是为人们设计的,就像计算机一样,我们需要清楚地向两者传达我们的意图。无论哪种代码最干净都是最好的,我们应该在可行的时候遵循惯例。我个人更喜欢这里的第二个选项,但我认为一般惯例是第一个。所以我认为你在大多数情况下使用call
,除非你需要最快的代码或者约定更改。
答案 1 :(得分:0)
func.call
旨在在需要提供该函数的替代(或任何)上下文时使用。
您的建议很奇怪,因为当您使用此模式定义函数时:**
function func(that,param,and,more,params...) {
//and in here use *that* and not *this*
}
它是:
不属于任何对象
在这种情况下,传递一个对象以充当this
没有任何意义,因为应该没有this.someThing
调用以
或属于不同的对象或被定义为对象的插件
在这种情况下,完全 func.call
会做什么,同时用冗余参数污染函数的定义。
更新:
以这种方式想想第二个例子 - 想象一些对象(你从同一个“类”调用的那个)允许注入任意函数,比如迭代对象的所有属性和一些摘要或者操纵或你有什么。
在Java中,常见的模式是创建Iterator并传递它,其主要目的是作为占位符,以便next
和hasNext
方法可以调用 - 因为Java实际上没有无对象函数。 (因为那里有一些额外的逻辑,但为了这个讨论,让我们不管它。)
JavaScript不需要这个!所有这些call
和apply
方法都没有需要来拥有一些额外的Iterator对象来保存它们。它们可以被定义为与任何对象“分离”,同时仍然打算在一个对象的上下文中使用(因此在它们的代码中使用this
)并注入到知道接受这些函数的代码中。
“主机”代码只需要call
或apply
代码,知道this
将引用自身 - 这个非常“主机”的对象。
这导致了更简洁,可重用和可移植的代码,IMO。
更新2:
查看更多here。
答案 2 :(得分:0)
您的模式将适用于此方案,但一般情况下它存在一些问题......
构造函数 - &gt;我们使用新关键字创建对象,其中&#39; this&#39;对象是自动创建并返回的(默认)也有与函数原型的链接。
在调用该功能时,有人可能会忘记通过该功能&#39;对象和您的代码将失败。在调用的情况下,如果传递null,则将其重置为全局对象(非严格模式,这是常见的)