通过私有函数和自执行函数来理解JavaScript

时间:2013-12-01 06:02:56

标签: javascript scope execute-immediate private-functions

我正在阅读Angus Croll understanding JS this博客并找到了这个

var a = {
  b: function() {
    var c = function() {
      return this;
    };
    return c();
  }
}; 

a.b();//window

在我看来,在调用c时,c在b里面。这应该是调用上下文(纠正我,如果我错了)。当它执行时,为什么c()的上下文(this)是窗口?

我在blog

中找到了另一个例子
var a = {
  b: function() {
    return (function() {return this;})();
  }
};

a.b(); //window

为什么b的上下文是窗口?匿名函数是否始终在全局上下文中运行?

2 个答案:

答案 0 :(得分:2)

这是了解this(双关语)的好方法:

函数内this的值由函数调用的方式决定。除了一个例外,它与定义函数的位置,它可以嵌套在其中的其他函数,它被定义为哪个对象,它是什么类型的函数,或者其中任何一个都没有关系。

当您使用foo.bar()foo[bar]()等方法调用来调用函数时,函数内的thisfoo对象。

当您使用foo()之类的普通函数调用调用函数时,函数中的thiswindow对象,或者如果函数使用严格模式,则为{{1} }。

这是一个例外 - 如果函数本身或其周围的代码有undefined,它会更改"use strict";以进行普通函数调用。对于不应该产生影响的优秀代码 - 您不应该编写依赖于this作为this对象的代码。

否则,您关心的是对象window在方法调用中引用的内容。而且这总是取决于函数的调用方式,而不是它的定义方式。

让我们来看看你的第一个例子。

当您致电this时,您正在调用a.b()作为b对象的方法。因此,在a函数中,bthis相同。

碰巧的是,由于a函数永远不会对b做任何事情,因此我们没有任何好处。它只是将this称为普通函数。因此,在c()内,cthis对象,如果您处于严格模式,它将是window

undefined函数只返回其c值或this。这也是window的返回值。这就是为什么您看到b的结果:这一切都来自代码如何调用windowb函数。

现在关于第二个例子:嗯,这只是非常模糊的代码,不是吗?谁会写这段代码并期望任何人乍看之下理解它?

因此,让我们把它变成一种更易阅读的形式。这一行是问题所在:

c

让我们取出带括号的函数表达式:

    return (function() {return this;})();

并将其分配给临时变量:

    (function() {return this;})

我们不再需要额外的括号,并且让代码缩进以便于阅读:

    var temp = (function() {return this;});

我们可以将 var temp = function() { return this; }; 变量称为temp语句中的函数:

return

现在我们可以将它放回代码示例中的 return temp(); 函数:

b

喂!该代码看起来不熟悉吗?实际上,除了var a = { b: function() { var temp = function() { return this; }; return temp(); } }; a.b(); //window 变量的名称之外,它与第一个示例相同。所以现在你明白为什么它和第一个一样。

答案 1 :(得分:1)

要查找的一个关键字是new关键字,它建立了一个新的上下文。看不到new?然后上下文没有改变,这意味着this没有改变。如果您从window内拨打此电话,那就是您的上下文,那就是您的this。 (如果您将call()apply()与范围一起使用,则会发生变化,但这显然不适用于此处。)