为什么这会返回对全局窗口对象的引用,即使'this'在另一个函数内

时间:2012-01-10 02:14:50

标签: javascript

if (typeof obj == 'undefined') {
  obj = {};
}

obj.thing = new function () {
  if (typeof this.global == 'undefined') {
    this.global = (function () {return this;})();
  }
}

this.global被分配给函数内部。那么,为什么这会返回对窗口对象的引用?

console.log(this) > DOMWindow
console.log(obj.thing.global) > DOMWindow
console.log(window) > DOMWindow

我希望能更好地理解这一点。

4 个答案:

答案 0 :(得分:1)

在ES 3和ES 5中,每个执行上下文(ES 3)或词法环境(ES 5)都有一个 this 关键字。根据输入全局或功能代码的规则设置该值,如ECMA-262 §10.4中所述。

在您的代码中,您有:

  this.global = (function () {return this;})();  

将调用匿名函数的结果分配给 this.global 。在该匿名函数中, this 的值是根据§10.4.3中的算法设置的。

由于在未设置 this 的值的情况下调用该函数,并且代码未处于严格模式,因此将 this 的值设置为全局对象( ,在浏览器中,通常是算法的第2步的窗口对象。

如果代码处于严格模式,那么匿名函数中 this 的值将是 undefined ,这是将分配给的值this.global

答案 1 :(得分:0)

this是一个始终返回当前上下文的关键字。试试这个:

if (typeof obj == 'undefined') {
  obj = {};
}

obj.thing = new function () {
  if (typeof this.global == 'undefined') {
    var self = this;
    this.global = (function () {return self;})();
  }
}

答案 2 :(得分:0)

问题是,在你自我调用的匿名函数中,上下文是那里的全局对象又名window。所以它返回window引用。即使new关键字创建一个新对象作为外部函数的上下文。外部上下文对于调用自我调用函数无关紧要。

为避免这种情况,您可以将代码稍微修改为:

obj.thing = new function () {
  if (typeof this.global == 'undefined') {
    this.global = (function (that) {return that;})(this);
  }
}

答案 3 :(得分:0)

javascript中的

this非常棘手。它并不意味着您认为它意味着什么,并且确实可以将其值替换为in lots of little ways,具体取决于调用函数的方式。虽然它可以帮助进行优化并为您提供一定程度的功能和javascript知识点,但在您对这个想法感到满意之前,您可能希望避免使用它。

最好将'this'视为一个特殊变量,其中包含函数调用者传入的额外信息。如果要锁定值,可以使用函数上的call / apply方法或者浏览器中的函数.bind或_.bind,如underscore.js。

var x = {
  name: "George",
  hiThere: function() { return "hi "+(this.name || "no value") ; }
}

x.hiThere(); // hi George

var thisWillBeGlobal = hiThere;
thisWillBeGlobal() // hi no value

var manuallyBoundToGeorge = function() {
  return x.hiThere();
}    
manuallyBoundToGeorge(); //hi George (always)
manuallyBoundToFred = function() {
  return x.hiThere.call({name: 'Fred'});
}
manuallyBoundToFred(); //hi Fred (always)

var hiGeorge = Function.bind(x.hiThere, x);
hiGeorge(); //hi George (always) - same as manual bind above

请注意,在旧浏览器中不能使用Function.bind,并且通常首选使用像underscroe的_.bind

这样的东西
  • 当您使用jquery等通过它传递信息的库时,您当然仍会使用this