【问题标题】:Why IIFE this keyword refers to window object..?为什么 IIFE 这个关键字指的是窗口对象..?
【发布时间】:2016-09-25 15:33:40
【问题描述】:

当我运行下面的 IFFE 时,为什么 this 关键字引用 window 对象而不是 a 变量?

var a = {
 printThis : function () {
 console.log('printThis', this);
  var inner = (function () {
    console.log('inner', this);
   })();
  }
};

a.printThis(); 

产生以下输出:

printThis **an object**

inner **window object**   <-- why..?

var a = {
  printThis: function() {
    console.log('printThis', this);
    var inner = (function() {
      console.log('inner', this);
    })();
  }
};

a.printThis();

【问题讨论】:

  • 你没有打电话给a.inner(),只是inner()。所以a 不会变成this
  • 但它也在一个 then 里面..
  • 没关系。每个函数都有自己的this。如果要保留外部this,则必须使用bindvar self = this 或“胖箭头”。
  • 你能解释一下这对 JavaScript 引擎是如何工作的吗?

标签: javascript javascript-objects


【解决方案1】:

考虑以下示例:

var a = {};
var b = {};
a.hello = function() { console.log(this); };
b.hello = a.hello;

在大多数编程语言中,b.hello() 将打印a,因为它们基于函数所在的this。函数在a中,所以this就是a。有道理,对吧?

然而,JavaScript 在这方面有点不同。它不是它在哪里,而是基于它是如何被调用的b.hello()b 上调用 hello,因此 this 设置为 b。这也是有道理的,因为 JavaScript 并没有一个函数“在哪里”的概念(不像 Java 中的方法,它总是与特定的类相关联),而且很难确定 a 是哪里它“是”。

因此,foo.bar() 将始终将this 设置为foo,以便调用bar(除非有人使用bind 或类似方法将this 提前绑定到特定值) .

现在,一个 IIFE 被调用...什么都没有,真的。这不是foo.bar() 的情况,它只是bar() 其中bar 是您的函数表达式。在这种没有foo 的情况下,它默认为window 对象。

有两种简单的解决方法:

  1. 在 IIFE 之外创建一个包含您感兴趣的值的变量:var that = this; 并在 IIFE 中使用 that 而不是 this,或者
  2. bind this 值:(function(){ CODE GOES HERE }).bind(this)();

【讨论】:

  • 在阅读此答案之前,我正要沮丧地翻转这张桌子,但我什至无法弄清楚this是什么!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 2014-04-12
  • 1970-01-01
  • 2023-04-10
  • 2019-06-22
  • 1970-01-01
  • 2022-11-19
相关资源
最近更新 更多