function.call方法有什么用?

时间:2012-09-03 15:18:59

标签: javascript

var x = 10;
var o = { x: 15 };

function f()
{
    alert(this.x);
}

f();
f.call(o);

第一个显示'10',第二个显示'15'作为输出值。任何人都可以告诉我在哪个实时场景中我会同时使用'call'方法和f()。

2 个答案:

答案 0 :(得分:3)

我只是在浏览未解答的问题,我不确定这对你是否会有所帮助,但它可能会帮助那些偶然发现这个问题的人。

在函数对象上使用call()方法可以覆盖函数引用的 this 对象。您已在自己的代码块中演示了预期的结果。

可以注意到apply()方法执行call()几乎相同的功能,但预期的参数格式除外。

call()期望参数采用逗号分隔格式,而apply()期望它们位于数组中。对于两者,第一个参数是将覆盖 this 的对象。

ECMA Spec

ECMA specification (pdf warning)可以说call()显示它用于更改特定函数的执行上下文:

  

13.2.1 [[Call]]

     

当使用此值和>参数列表调用Function对象F的[[Call]]内部方法时,将执行以下步骤:

     
      
  1. 让funcCtx成为使用F的值为函数代码建立新执行上下文的结果   [[FormalParameters]]内部属性,传递参数List args,以及此值中描述的值   10.4.3。
  2.   
  3. 让结果为评估作为F [[Code]]内部属性值的FunctionBody的结果。如果   F没有[[Code]]内部属性或者如果它的值是一个空的FunctionBody,那么结果是(正常,   undefined,empty)。
  4.   
  5. 退出执行上下文funcCtx,恢复先前的执行上下文。
  6.   
  7. 如果result.type是throw,则抛出result.value。
  8.   
  9. 如果result.type为return,则返回result.value。
  10.   
  11. 否则result.type必须正常。返回undefined。
  12.   

答案 1 :(得分:0)

  

任何人都可以告诉我在哪个实时场景中我会同时使用'call'方法和f()。

期望使用该对象作为 this 来调用作为对象方法的函数,例如使用内置的 Array.prototype.forEach 方法,该方法希望 this 是一个Array实例。

但是,该方法是通用的,因此实例不必是数组,它只需要是一个足以像方法一样工作的数组的对象。在大多数浏览器中,它可以传递一个NodeList,它是一个宿主对象(虽然有些浏览器不喜欢这样),所以你可以调用 forEach 将NodeList作为传递

Array.prototype.forEach.call(
  document.getElementsByTagName('*'),
  function(element){ 
    console.log('This element is a ' + element.tagName)
  }
);

放置在文档底部的脚本元素中,上面会将每个元素的标记名写入控制台。

上述电话有时会缩短为:

[].forEach.call(...)

创建一个新的Array实例,并使用其[[Prototype]]链访问 forEach

因此,您可以看到,对于数组实例需要普通的 forEach ,并且需要使用调用单独使用它。还有其他情况,可以通过将 this 设置为其他值(例如DOM元素上的侦听器)来调用方法。