使用“ this”关键字无法理解功能的行为

时间:2019-09-08 20:13:37

标签: javascript this

我试图弄清楚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}

我希望这里有人可以帮助我了解发生了什么,或者至少推荐给我更完整的资源。预先谢谢你!

2 个答案:

答案 0 :(得分:2)

  

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

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

  

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

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

  

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

不。函数中的this甚至不会被求值,也永远不会调用该函数。您只调用了bar,然后将返回的函数与obj进行了比较。

  

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

…然后控制台会向您显示一个功能对象!

答案 1 :(得分:1)

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

如此

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

console.log(obj.bar()() === obj); //should give you true