使用“呼叫”与“传递”;这";在JavaScript中

使用“呼叫”与“传递”;这";在JavaScript中,javascript,performance,oop,optimization,Javascript,Performance,Oop,Optimization,我知道,如果您有一些javascript函数,并且希望调用它,以便在其中使用this不会引用直接调用它的对象,那么您可以使用func.call(thatObject,param,以及更多的params…) 但是假设您是func的作者,func的唯一用法是通过func.call, 为什么不将其定义为: function func(that,param,and,more,params...) { //and in here use *that* and not *this* } 是的,它看起

我知道,如果您有一些javascript函数,并且希望调用它,以便在其中使用
this
不会引用直接调用它的对象,那么您可以使用
func.call(thatObject,param,以及更多的params…

但是假设您是
func
的作者,func的唯一用法是通过func.call,
为什么不将其定义为:

function func(that,param,and,more,params...) {
   //and in here use *that* and not *this*
}
是的,它看起来不那么“酷”,因为它不是对象的方法, 但是,如果func的唯一用法是通过func.call,那么这一切似乎只是额外的代码和开销


我是不是遗漏了什么?或者,我在其中看到的这个模式的源代码只是“过OOed”

func.call
用于需要提供函数的替代(或任何)上下文时

您的建议很奇怪,因为当您使用此模式定义函数时:**

function func(that,param,and,more,params...) {
   //and in here use *that* and not *this*
}
要么是:

不属于任何对象

在这种情况下,传递对象作为
this
没有任何意义,因为不应该有
this

属于不同的对象或定义为对象的插件

在这种情况下,它确实执行
函数调用
相同的操作,同时用冗余参数污染函数的定义

更新:

以这种方式考虑第二个例子——假设某组对象(您从同一个“类”中调用的对象)允许插入仲裁函数,比如对对象的所有属性进行迭代和一些总结或操作,或者您拥有的其他内容

在Java中,常见的模式是创建一个迭代器并传递它,它的主要目的是充当某种占位符,以便调用
next
hasNext
方法,因为Java并没有真正的无对象函数。(当然这里还有一些附加的逻辑,但是为了讨论这个问题,我们还是先别管它了)

JavaScript不需要这样做!所有这些
调用
应用
方法都不需要
有一些额外的迭代器对象来保存它们。它们可以被定义为与任何对象“分离”,同时仍打算在一个对象的上下文中使用(因此
在它们的代码中使用此
用法),并注入知道接受此类函数的代码中

“主机”代码不仅需要调用它们,还需要应用它们,因为它知道
这个
将引用它自己-这个“主机”对象

这导致了一个更简洁、可重用和可移植的代码IMO

更新2:


请参阅更多信息。

性能差异似乎很大。使用

func(){
  //code here, this.something
}
func.call(thatObject)
根据前两次测试,速度大约是使用时的8倍

func(that){
  //code here, that.something
}
func(thatObject)
自己测试一下


但最终,速度本身很少是我们使用代码的最重要因素。代码是为人设计的,就像它是为计算机设计的一样,我们需要将我们的意图清楚地传达给两者。使代码最干净的是最好的,只要可行,我们就应该遵循约定。我个人更喜欢第二种选择,但我认为一般惯例是第一种。因此,我认为您在大多数情况下都会使用
call
,除非您需要尽可能快的代码,或者约定发生变化。

您的模式在这种情况下会起作用,但通常会出现一些问题

  • 构造函数函数->我们通过使用new关键字创建对象,其中“this”对象自动创建并返回(默认值),并且还具有与函数原型的链接

  • 调用函数时,可能有人忘记传递“that”对象,您的代码将失败。在调用的情况下,如果传递null,则会重置为全局对象(非严格模式,这是常见的)


  • 为什么这被标记为“性能”?“优化”子问题在哪里?@Tomalak,因为可能存在性能差异,一个调用额外的函数以获得适当的范围,而另一个则发送带有指向对象指针的变量。事实上,你有130k以上的销售代表,为什么我要和你争论…@RustyToms:那么,这将是过早的优化。性能标记的唯一有效问题是包含探查器报告的问题。直接调用函数与通过
    .call()
    .apply()
    调用函数之间没有性能差异。你为什么这么想?你量过尺寸了吗?这有关系吗?你确定你真的对性能影响感兴趣,还是你真的想问为什么
    .call()
    /
    .apply()
    首先存在?@ABFORCE:所有JavaScript函数都可以使用
    call
    apply
    调用。这是语言的基本特性之一。也许我选择调用第一个参数
    ,它不是一个很好的参数:),但关键是它是一个作用于某个对象的函数。但不属于它。这就是为什么我一开始觉得奇怪的原因,函数的作者选择在函数中使用
    this
    ,然后调用它,而不是仅仅将对象作为参数传递。“JavaScript不需要这样做”?还是“没有”?我理解可以这样做(即“独立”在代码中引用这些函数的函数和使用这些函数的对象,就好像它们拥有via call一样。我尊重你的意见,但我觉得这个代码模式没有更简洁、可重用或可移植的。此外,看到性能差异和事实,我想我会选择直接调用模式……如果你没有看到h我发现你的编码方式非常难看,我想你根本不会注意到它们之间的区别