嵌套对象文字中“ this”的词汇上下文

时间:2019-09-03 10:30:33

标签: javascript ecmascript-6 arrow-functions

我之所以问,是因为我已经读过类似(但不相等)的问题。

据我了解,我明白为什么此代码有效:

let myObj = {
  name: 'inner text',
  myFunction: () => {
    console.log("before text " + this.name + " after text");
  }
}
myObj.myFunction();

原因:创建箭头函数(myObj)的上下文属于全局范围(取决于严格模式,为windowundefined等等。

我明白了。但是在嵌套对象常量的情况下,难道不是外部对象常量是arrow函数的继承上下文吗?

let outer = {
  name: 'outer',
  obj: {
    name: 'inner',
    myFunction: () => {
      console.log("before text " + this.name + " after text");
    }
  }
}
outer.obj.myFunction();

我希望this引用outer的上下文,这是嵌套obj的对象文字。
事实并非如此,也是我无法正确理解这种继承的词汇范围的原因。

有人能解释为什么会这样吗?

2 个答案:

答案 0 :(得分:1)

  

但是在嵌套对象文字的情况下,难道不应该像下面的示例那样将外部对象文字作为arrow函数的继承上下文吗?

否。

箭头功能复制this当前值;

var object = {
     a: this,
     b: { 
         a: this,
         b: {
             a: this
         }
     } 
}

嵌套多少级无关紧要,this的值不会改变。

由于对象文字的每个级别都出现在同一函数中,因此它们都具有相同的this值。

答案 1 :(得分:0)

有很多方法可以实现您想要的。最紧凑的方法是使用getter,如下所示:

let outer = {
  name: 'outer',
  obj: {
    name: 'inner',
    get myFunction() {
      console.log("before text " + this.name + " after text");
      return (this.name);
    }
  }
}
outer.obj.myFunction;

在getter / setter内部,您的上下文保证是对象实例(嵌套最多)(请记住,每个内部对象都是Object的“独立”实例,getter / setter将属于最近的实例)。 / p>

代码的问题在于,箭头函数在创建对象时保留了执行上下文。

实现预期行为的另一种方法是保存手动绑定的方法,如下所示:

let outer = {
  name: 'outer',
  obj: {
    name: 'inner'
  }
}
outer.obj.myFunction = (function () {console.log("before text " + this.name + " after text");}).bind(outer.obj);
outer.obj.myFunction();