箭头函数中的'这个'不显示词义范围。

问题描述 投票:0回答:2

我试图理解箭头函数中'this'的词法范围。我尝试了以下代码

const obj1 = {
  name: "obj1name",
  method: function(){
    return () => {return this.name};
  }
};

const arrowFunc1 = obj1.method();

console.log(arrowFunc1());

const obj2 = {
  name: "obj2name",
  method: function(){
    return obj1.method();
  }
};

const arrowFunc2 = obj2.method();

console.log(arrowFunc2());

这就得到了输出-----------------------------------------------。

obj1name
obj1name

正如预期的那样,箭头函数内的'this'在词法上被限定为obj1,因此无论我们如何调用它,它都会打印出'obj1name'。直到这里,一切都很好。然后我决定不定义obj2.method,而是直接将obj1.method复制到其中----------。

const obj1 = {
  name: "obj1name",
  method: function(){
    return () => {return this.name};
  }
};

const arrowFunc1 = obj1.method();

console.log(arrowFunc1());

const obj2 = {
  name: "obj2name",
  method: obj1.method
};

const arrowFunc2 = obj2.method();

console.log(arrowFunc2());

这就得到了输出-----------------------------------------------。

obj1name
obj2name

我不明白为什么它会打印'obj2name'。

我的理解是,箭头函数是在obj1.method中定义的,所以它的词法范围在其中。因此,它应该从obj1.method即obj1中获取'this'的值。

我到底错在哪里?

javascript this arrow-functions
2个回答
1
投票

它的词法范围是:你在obj1中定义了一个函数(箭头),但在obj2中调用了它--obj2的词法范围是obj2--所以你在那里调用的方法按理说可以工作。

代码段中的 console.logs 显示了这个问题。

const obj1 = {
  name: "obj1name",
  method: function(){
    return () => {return this.name};
  }
};

const arrowFunc1 = obj1.method();

console.log(arrowFunc1());

const obj2 = {
  name: "obj2name",
  method: obj1.method
};

const arrowFunc2 = obj2.method();

console.log(arrowFunc2());

// these console.logs show your problem:
console.log('obj1:', obj1)
console.log('obj2:', obj2)

在你的例子中, function()this - 并且 function() 是在 obj2.

也许这个片段可以帮助你理解更多。

// extracted the function, but left the "this"
// just calling the function in itself would throw an
// error, but inside an object (that has a name property)
// it works nicely
const fn = function() {
  return () => {
    return this.name
  }
}

const obj1 = {
  name: "obj1name",
  method: fn
};

const arrowFunc1 = obj1.method();

console.log(arrowFunc1());

const obj2 = {
  name: "obj2name",
  method: fn
};

const arrowFunc2 = obj2.method();

console.log(arrowFunc2());

// these console.logs show your problem:
console.log('obj1:', obj1)
console.log('obj2:', obj2)

最后一个片段:

const obj1 = {
  name: "obj1name",
  method: function() {
    return () => {
      return this.name
    };
  }
};

const arrowFunc1 = obj1.method();

console.log(arrowFunc1());

// if you want to call with obj1, then it's not enough to add the
// function - you have to CALL (invoke) it
const obj2 = {
  name: "obj2name",
  method: obj1.method()
};

// see that there're no parantheses after obj2.method - its
// value is resolved when creating obj2 by INVOKING the function
const arrowFunc2 = obj2.method;

console.log(arrowFunc2());

// these console.logs show your problem:
console.log('obj1:', obj1)
console.log('obj2:', obj2)

0
投票

这个:

const obj1 = {
  name: "obj1name",
  method: function(){
    return () => {return this.name};
  }
};

应该是这个


const obj1 = {
  name: "obj1name",
  method: () => {return this.name}
};

通过将箭头函数包装在一个常规函数中... ...作用域再次成为调用者的作用域.

© www.soinside.com 2019 - 2024. All rights reserved.