简体   繁体   English

为什么在调用apply()或call()时,“ this”指向函数内部的窗口?

[英]Why 'this' points to window inside a function when apply() or call() is being called?

I'm reading Nicholas Z.Zakas' Professional JavaScript for web developer 3rd edition and inside the Reference types chapter I got a bit confused at the function type part. 我正在阅读Nicholas Z.Zakas针对Web开发人员第三版的专业JavaScript,在“引用类型”一章中,我对函数类型部分有些困惑。

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

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

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

He says: 他说:

"In this example, callSum1() executes the sum() method, passing in this as the this value (which is equal to window because it's being called in the global scope) and also passing in the arguments object." “在此示例中, callSum1()执行sum()方法,将this作为this值传入(由于在全局范围内被调用,因此等于window ),并且还传入arguments对象。”

I understand what he says, but I don't understand the why. 我明白他说什么,但不明白为什么。 This supposed to point to the function doesn't it? This应该指向功能不是吗? Now I'm confused that it's pointing to the window because it's being called in the global scope .. 现在我很困惑它指向窗口,因为它是在全局范围内被调用的。

Can someone be kind to explain it to me? 有人可以向我解释吗? :) :)

I'm not sure if I will or I have to use this technique later, but I want to make sure I understand it, especially the this part. 我不确定是否会或以后必须使用此技术,但是我想确保自己了解它,尤其是这一部分。 More details about this and its usage will come in the OOP section, but it's now an interesting question. 有关this及其用法的更多详细信息将在“ OOP”部分中,但现在这是一个有趣的问题。

Thanks in advance! 提前致谢!

The value of this depends on how you call a function. this取决于你如何调用一个函数。

If you call a function using call or apply then the value of this will be the first argument to that function. 如果您在使用调用一个函数callapply则价值this将是第一个参数传递给函数。

Here you have sum.apply(this, arguments); 在这里,您有sum.apply(this, arguments); so it will pass the current value through. 因此它将通过当前值。 As usual, that value is determined by how you call the function. 通常,该值由调用函数的方式确定。

Since you call callSum1(10,10) with no context, this will be window . 由于您在没有上下文的情况下调用callSum1(10,10)this它将是window

(If you were in strict mode, it would be undefined . If you weren't in a browser, it would be whatever the default object of the JS environment you were using was). (如果处于严格模式下,它将是undefined 。如果您不在浏览器中,那么它将与您所使用的JS环境的默认对象无关)。

Here: 这里:

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

...you're calling callSum without doing anything to set this during the call, and so this is defaulted to the global object ( window , on browsers). ......你打电话callSum没有做任何事情来设置this在通话过程中,因此this被默认为全局对象( window ,在浏览器上)。 (In loose mode; in strict mode, this would have been undefined .) (在宽松模式下;在严格模式下, this将是undefined 。)

Since you're then using apply and passing that same this into it: 从那时起,你使用apply ,并通过同this到它:

return sum.apply(this, arguments);

...naturally the global object is also used when calling sum . ...自然地,在调用sum时也会使用全局对象。

I understand what he says, but I don't understand the why. 我明白他说什么,但不明白为什么。 This supposed to point to the function doesn't it? 这应该指向功能不是吗?

No, this almost never refers to functions. 不, this几乎从不涉及功能。 (It can, of course, it just very rarely does.) (当然,它很少会这样做。)

Now I'm confused that it's pointing to the window because it's being called in the global scope .. 现在我很困惑它指向窗口,因为它是在全局范围内被调用的。

It's not because it's being called in the global scope; 这不是因为它在全局范围内被调用。 it would be the same if it were being called from inside a function. 如果从函数内部调用它,将是相同的。 What matters isn't where the call occurs, but how . 重要的不是呼叫发生在哪里 ,而是如何发生。 Any time you call a function without doing anything to set this , in loose mode, this during the function call will be the global object. 你调用一个函数没有做任何事情任何时候设置this ,在宽松的模式, this在函数调用期间将是全局对象。 It doesn't have to be at global scope; 它不必处于全球范围内; what matters is how you call the function. 重要的是如何调用该函数。

The rule is actually a lot simpler than people make it out to be: If you call a function without doing anything to set this , during the call, this will be the global object (in loose mode) or undefined (in strict mode). 该规则实际上是一个简单了很多比人做出来是:如果你调用一个函数没有做任何事情来设置this ,在通话过程中, this将是全球对象(松散模式)或undefined (严格模式)。 Here are the things you can do to set this during a function call: 以下是你可以做把东西this函数调用时:

  1. Call the function as part of an expression getting the function from a property on an object. 调用函数作为表达式的一部分,从对象的属性获取函数。 For example, foo.bar(); 例如foo.bar(); retrieves a reference to the function from the bar property on foo , then calls bar . foobar属性中检索对该函数的引用,然后调用bar Because we did it that way, during the call to bar , this refers to foo . 因为我们是这样做的,所以在调用bar期间, this指的是foo

  2. Call the function using .call or .apply ; 通过调用函数.call.apply ; this will be what you pass in the first argument. this就是您在第一个参数中传递的内容。 (In loose mode, if you pass undefined , null , or a non-object in the first argument, during the call this will be the global object. In strict mode, it'll be what you pass.) (在松散模式,如果传递undefinednull ,或非对象在第一个参数,在通话过程中this将是全局对象。在严格的模式,这将是你传递什么。)

  3. Call a bound function. 调用绑定函数。 That's a function created via Function#bind (an ES5 feature). 这是通过Function#bind (ES5功能)创建的Function#bind Bound functions have this "baked into" them. 绑定函数将this “嵌入”到它们中。

More (on my blog) : 更多(在我的博客上)

Under the Window object part ~20 pages later, I'm reading this: "As mentioned previously, the this value is equivalent to the Global object when a function is executed with no explicit this value specified (either by being an object method or via call() / apply() )." 下的窗口对象部分20〜页之后,我读这样的:“如前面所提到的, this值相当于当一个函数与没有明确的执行全局对象this或者通过作为一个对象的方法,或通过指定的值( call() / apply() ”。 :) :)

Maybe I didn't get it before, but now it's clear with his words as well. 也许我以前没听懂,但现在他的话也很清楚。 By the way, the book is awesome! 顺便说一下,这本书太棒了! Now with Math object I can understand much more the apply() method, too. 现在,通过Math对象,我也可以了解更多apply()方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM