函数(带变量)-> 函数-> 粗箭头函数-> 此处显示的第一个函数的变量?

function (with variable) -> function -> fat arrow function- >variable from first function showing here?

我正在学习词法 this 的传递,我的理解是粗箭头从自身或其上方的函数获取 "this"。如果这是一个常规函数,我的理解是它不会从比这个更高的函数中得到 this 。例如,这是我认为不应该 运行:

的代码

function test() {
  this.a = 5; // test()' variable
  this.b = function() {
    //this is a fat arrow function so console log below could grab the this from this function's space, but not higher than this, but it does?
    this.c = setTimeout(() => {
      console.log(this.a);
    }, 1000);
  }
}
var d = new test();
d.b();

所以我希望 console.log 语句想要打印出 this.a 。它不存在于粗箭头函数上下文中,因此它上升了一个级别到匿名函数级别。这里也没有this.a。这是一个普通的 non-fat 箭头函数,这意味着我理解的词法范围应该到此为止,它不应该再上升,但它确实上升了,我不确定为什么。为什么会这样?

因为您正在调用函数 b 作为 d.bthis 是对象 d。所以 this.a 等价于 d.a。正如您已经观察到的,箭头函数将从其父范围携带 this,因此它能够将 this.a 解析为 d.a.

function test() {

  this.a = 5; // test()' variable
  this.b = function() {
    console.log("this.a in b: ", this.a);
  
    this.c = setTimeout(() => {
      console.log("this.a in c: ", this.a);
    }, 1000);
  }
}

var d = new test();
d.b();


如果您将 d.b 拉入一个单独的变量,然后调用它,会发生什么情况?你得到 undefined - 因为 b 里面的 this 现在指的是全局范围。

function test() {

  this.a = 5; // test()' variable
  this.b = function() {
    console.log("this.a in b: ", this.a);
    console.log("this === window: ",this === window);
  
    this.c = setTimeout(() => {
      console.log("this.a in c:", this.a);
    }, 1000);
  }
}

var d = new test();
var myNewFunction = d.b;

myNewFunction();

阅读 this(双关语)

"When a function is called as a method of an object, its this is set to the object the method is called on"

考虑这个简化的例子:

"use strict";

var obj = {
  name: "obj",
  a: function() {
    return this
  }
}
var a = obj.a
var obj2 = {
  name: "obj2"
}
obj2.a = a

console.log(
  obj.a(), // => obj
  a(), // => window | undefined (based on strict mode)
  obj2.a() // => obj2
)

同样,在您的示例中,调用 d.b() 会将 this 设置为 b 中的 d。在你的箭头函数中,这个上下文将被保留。