当调用apply()或call()时,为什么'this'指向函数内的窗口?

时间:2014-01-03 09:17:01

标签: javascript function this

我正在阅读Nicholas Z.Zakas的面向Web开发人员第3版的专业JavaScript,在参考类型章节中,我对功能类型部分感到有些困惑。

function sum(num1, num2){
return num1 + num2;
}

function callSum1(num1, num2){
return sum.apply(this, arguments);
}

alert(callSum1(10,10)); //20

他说:

“在此示例中,callSum1()执行sum()方法,将this作为this(等于{{ 1}}因为它在全局范围内调用并传入window对象。“

我明白他的意思,但我不明白为什么。 arguments应该指向函数不是吗?现在我很困惑它指向窗口,因为它在全局范围内被调用..

有人可以帮我解释一下吗? :)

我不确定以后我是否会使用这种技术,但我想确保理解它,尤其是这一部分。有关This及其用法的更多详细信息将在OOP部分中提供,但现在这是一个有趣的问题。

提前致谢!

3 个答案:

答案 0 :(得分:3)

this的值取决于您如何调用函数。

如果使用callapply调用函数,则this的值将是该函数的第一个参数。

这里有sum.apply(this, arguments);所以它会传递当前值。像往常一样,该值取决于您调用函数的方式。

由于您在没有上下文的情况下致电callSum1(10,10)this将为window

(如果你处于严格模式,它将是undefined。如果你不在浏览器中,那就是你正在使用的JS环境的默认对象。)

答案 1 :(得分:1)

下面:

alert(callSum1(10,10)); //20

...您在调用期间没有做任何设置callSum的事情而调用this,因此this默认为全局对象(window,浏览器)。 (在宽松模式下;在严格模式下,this将为undefined。)

因为您正在使用apply并将相同的this传递给它:

return sum.apply(this, arguments);

...当然,在调用sum时也会使用全局对象。

  

我明白他的意思,但我不明白为什么。这应该指向功能不是吗?

不,this几乎从不涉及功能。 (它当然可以很少发生。)

  

现在我很困惑它指向窗口,因为它在全局范围内被调用..

这不是因为它在全球范围内被调用;如果从函数内部调用它将是相同的。重要的不是发生调用,而是如何。每当你调用一个函数而没有做任何事情来设置this时,在松散模式下,函数调用期间的this将是全局对象。它不必在全球范围内;重要的是你如何称呼这个功能。

规则实际上比人们做出的要简单得多:如果你在没有做任何设置this的情况下调用函数,那么在调用期间,this将成为全局对象(在松散模式)或undefined(严格模式)。以下是在函数调用期间设置this可以执行的操作:

  1. 将函数作为表达式的一部分调用,从对象的属性获取函数。例如,foo.bar();bar上的foo属性中检索对该函数的引用,然后调用bar。因为我们是这样做的,所以在致电bar期间,this指的是foo

  2. 使用.call.apply调用该函数; this将是您在第一个参数中传递的内容。 (在松散模式下,如果在第一个参数中传递undefinednull或非对象,则在调用this期间将成为全局对象。在严格模式下,它'这将是你通过的。)

  3. 调用绑定函数。这是通过Function#bind(ES5功能)创建的功能。绑定函数将this“加入”它们。

  4. 更多(在我的博客上)

答案 2 :(得分:0)

在Window对象部分~20页之后,我正在读这个: “如前所述,this值等同于执行函数时的全局对象指定了显式this值(通过作为对象方法或通过call() / apply())。“ :)

也许我之前没有得到它,但现在也很清楚他的话。顺便说一下,这本书太棒了!现在有了Math对象,我也可以理解更多的apply()方法。

var values = [1,2,3,4,5,6];
var max = Math.max.apply(Math, values);