【问题标题】:Lexical context of 'this' in Nested Object Literals嵌套对象文字中“this”的词法上下文
【发布时间】:2019-09-03 10:30:33
【问题描述】:

我之所以这么问,是因为我读过关于这个问题的类似(但不相等)的问题。

据我所知,我明白为什么这段代码会工作:

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

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

我明白了。但是在嵌套对象字面量的情况下,不应该是外部对象字面量作为箭头函数的继承上下文,如下例所示?

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

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

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

【问题讨论】:

  • 词法作用域是一样的,只有函数创建作用域。只是不要将箭头函数用作方法。或者,如果您一定要这样做,请使用带有 new 的旧的良好构造函数,那么您将拥有正确的 this 值的适当范围。
  • 作用域是基于函数/构造函数创建的。所以当你使用箭头函数时,作用域是与父函数关联的,而不是对象
  • 如果普通对象字面量的值没有特殊的this 值,为什么嵌套对象字面量会有所不同?

标签: javascript ecmascript-6 arrow-functions


【解决方案1】:

但是在嵌套对象字面量的情况下,外部对象字面量不应该是箭头函数的继承上下文,如下例所示?

没有。

箭头函数复制this当前值;

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

不管嵌套多少层,this 的值都不会改变。

由于对象字面量的每一层都出现在同一个函数中,它们都得到相同的this 值。

【讨论】:

    【解决方案2】:

    有很多方法可以实现您想要的。最紧凑的可能是使用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 将属于最近的实例)。

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

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

    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();

    【讨论】:

      猜你喜欢
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 1970-01-01
      • 2013-09-08
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多