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

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

f();
f.call(o);

第一个将显示“10”,第二个将显示“15”作为输出值。谁能告诉我在哪个实时场景中我会同时使用“call”方法和 f()。

4

2 回答 2

3

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

在函数对象上使用该call()方法允许您覆盖this要由函数引用的对象。您已经在自己的代码块中展示了预期的结果。

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

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

ECMA 规范

ECMA 规范(pdf 警告)说明了call()它在更改特定函数的执行上下文中的用途:

13.2.1 [[呼叫]]

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

  1. 令 funcCtx 为使用 F 的 [[FormalParameters]] 内部属性的值、传递的参数 List args 和 10.4.3 中所述的 this 值为函数代码建立新执行上下文的结果。
  2. 让 result 是对作为 F 的 [[Code]] 内部属性的值的 FunctionBody 求值的结果。如果 F 没有 [[Code]] 内部属性,或者它的值为空 FunctionBody,则结果为(正常、未定义、空)。
  3. 退出执行上下文funcCtx,恢复之前的执行上下文。
  4. 如果 result.type 被抛出,则抛出 result.value。
  5. 如果返回result.type,则返回result.value。
  6. 否则 result.type 必须是正常的。返回未定义。
于 2013-02-26T16:17:47.517 回答
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 ,并通过call单独使用它。还有其他情况,可以调用方法并将其设置为其他值(例如,DOM 元素上的侦听器)。

于 2015-01-16T22:45:17.260 回答