使用“Call”调用匿名函数时如何分配“This”?

时间:2012-11-15 17:27:36

标签: javascript oop call this

来自MDN

var animals = [
  {species: 'Lion', name: 'King'},
  {species: 'Whale', name: 'Fail'}
];

for (var i = 0; i < animals.length; i++) {
  (function (i) {
    this.print = function () {
      console.log('#' + i  + ' ' + this.species + ': ' + this.name);
    }
    this.print();
  }).call(animals[i], i);
}

在上面的例子中,“this”如何在“animals”循环中的匿名函数中使用?我很好奇为什么“这个”引用动物对象而不是窗口。

例如,如果我从参数中删除 animals [i] ,那么一切都是未定义的。这是否意味着匿名函数从他们收到的第一个参数派生出他们的“身份”,或者是其他事情继续发生?

提前致谢!

3 个答案:

答案 0 :(得分:3)

您自己引用的documentation of function.call()中是否解释过这个问题?

fun.call(thisArg[, arg1[, arg2[, ...]]])
     

<强>参数

     

thisArg this的价值用于召唤乐趣。 [...]

以后:

  

<强>描述

     

调用现有函数时,可以指定其他this对象。

所以你是对的,animals[i]在函数中被用作this。您可以将其视为隐式隐藏参数,该参数始终具有this名称。

答案 1 :(得分:2)

这是这一部分:

  }).call(animals[i], i);

通过.call()调用,this的值已明确指定。

Function原型提供了两种类似的功能:.call().apply()。它们都允许使用某个特定值(对象的引用)作为this调用函数(任何函数,匿名与否 - 没有实际区别)。

调用函数时,this的值始终以某种方式设置。如果函数的引用由.[ ]表达式确定:

something.fn( whatever );

something[ expression ](whatever);

然后this的值是基础对象的值(上例中的“某事”)。 Eich先生称之为“接收器”,如果你想到像Smalltalk消息这样的函数调用,那就有意义了。

如果您调用没有基础对象的函数,则this的值可以是全局对象,如果您处于“严格”模式,则为null

答案 2 :(得分:1)

因为您使用的call定义为:

call(thisScope, args)

因此,您animal[i]传递thisScope的事实意味着this == animal[i]