【问题标题】:Can't understand the behaviour of functions with "this" keyword无法理解带有“this”关键字的函数的行为
【发布时间】:2019-09-08 20:13:37
【问题描述】:

我正在尝试找出 JavaScript 中“this”关键字的行为。一般来说,我了解它在函数调用的不同上下文中的行为方式,但是当它是箭头函数的一部分时,我遇到了一些麻烦。

我使用 MDN 作为信息来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#Arrow_functions。 我已经掌握了在箭头函数的情况下“this”保留与函数定义的上下文相对应的值的一般概念,但是在玩该部分的最后一个示例时我开始遇到麻烦。

示例如下:

var obj = {
  bar: function() {
    var x = (() => this);
    return x;
  }
};

var fn = obj.bar();

console.log(fn() === obj); //true

正如预期的那样,控制台返回 true。但是,这是我的第一个疑问,我不明白为什么当我直接将 obj 与 obj.bar() 进行比较时它返回 false,因为我假设 obj.bar() 和 fn() 调用相同的函数:

var obj = {
  bar: function() {
    var x = (() => this);
    return x;
  }
};

console.log(obj.bar() === obj); //false

我开始使用代码试图找到更多意想不到的行为,但还有一些疑问。第二个:当我更改bar的定义类型时,函数中的“this”显然开始引用全局对象,尽管我认为该函数被称为obj的方法。 ¿ 结果不应该是相反的吗? ¿ 是不是因为现在“this”指的是 fn 的上下文?

var obj = {
  bar: function() {
    var x = function() {
      return this;
    };
    return x;
  }
};

var fn = obj.bar();

console.log(fn() === obj); //false
console.log(fn() === this); //true

第三个疑惑:如果我再次省略 fn 并在比较中直接使用 obj.bar() ,我再次发现意外的结果。在这种情况下,函数中的“this”既不指全局对象,也不指 obj(我希望是第二个,因为 bar() 被称为 obj 的方法)。

var obj = {
  bar: function() {
    var x = function() {
      return this;
    };
    return x;
  }
};

console.log(obj.bar() === obj); //false
console.log(obj.bar() === this); //false

当我尝试直接查看 obj.bar() 返回的值时,我无法从控制台获得太多帮助:

console.log(obj.bar());
//With arrow definition: () => { length:0
//                               name:x }
//With the second definition: f() => { length:0
//                                     name:"bar"
//                                     prototype: bar}

我希望这里有人可以帮助我了解发生了什么,或者至少向我推荐一个更完整的资源。提前谢谢!

【问题讨论】:

  • fn() = (obj.bar())() 不是 obj.bar()(你调用了两次)

标签: javascript this


【解决方案1】:

我假设 obj.bar() 和 fn() 调用相同的函数

不,obj.bar() 返回函数 x。它正在创建一个闭包。

函数中的“this”显然开始引用全局对象,尽管我认为该函数是作为 obj 的方法调用的

不,fn 没有作为 obj 上的方法被调用,只有 bar 被调用。 fn() 被称为普通函数。

如果我再次省略 fn 并在比较中直接使用 obj.bar() ,则函数中的“this”既不指全局对象也不指 obj

没有。函数中的this 甚至从未被评估过,该函数从未被调用过。您只调用了bar,然后将返回的函数与obj 进行了比较。

当我尝试直接查看 obj.bar() 返回的值时

…然后控制台会显示一个函数对象!

【讨论】:

    【解决方案2】:

    您正在查看的是 obj.bar() 重新分配一个分配给变量 fn 的函数,然后调用 fn fn()

    所以

    var obj = {
      bar: function() {
        var x = (() => this);
        return x;
      }
    };
    
    console.log(obj.bar()() === obj); //should give you true
    

    【讨论】:

      猜你喜欢
      • 2019-01-05
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 2017-12-15
      • 1970-01-01
      相关资源
      最近更新 更多