Object.defineProperty,从类内部获取“ this”,而不是“ window”

时间:2019-12-02 12:26:04

标签: javascript

简而言之,我试图在window中定义一个变量,该变量与类中的myValue保持同步。因此window.myGlobalVarName在类中应始终等于myValue

我正在使用Object.defineProperty来尝试阻止在window中重新分配变量。

但是,每当调用get()时,thiswindow对象,而不是类中的this。我在这里错过明显的东西吗?有很多使用get()返回类中使用this的值的示例-我在做什么不同?

class MyClass {
  constructor() {
    this.myValue = 1
    this.globalVarName = "myGlobalVarName"
    this.setGlobalObject()
  }

  setGlobalObject() {
    if (typeof window !== "undefined") {
      Object.defineProperty(window, this.globalVarName, {
        configurable: false,
        enumerable: true,
        get() { return this.myValue } // "this" is actually "window"
      })
    }
  }
}

我可以解决返回函数值的问题,但是我可以这样做更好吗?

  setGlobalObject() {
    const getMyValue = () => this.myValue // Return current value of this.myValue
    if (typeof window !== "undefined") {
      Object.defineProperty(window, this.globalVarName, {
        configurable: false,
        enumerable: true,
        get() { return getMyValue() } // Returns the actual value from the class
      })
    }
  }

1 个答案:

答案 0 :(得分:3)

  

但是,只要调用get()this就是窗口对象,而不是类中的this

这就是大多数函数和方法在JavaScript中的工作方式,this调用的方式设置,而不是由它们的定义位置决定。 this question的答案中有详细信息。您的get函数是相同的,因为它是传统函数(使用方法语法编写)。

要从定义函数的位置获取this,请使用arrow function

class MyClass {
  constructor() {
    this.myValue = 1
    this.globalVarName = "myGlobalVarName"
    this.setGlobalObject()
  }

  setGlobalObject() {
    if (typeof window !== "undefined") {
      Object.defineProperty(window, this.globalVarName, {
        configurable: false,
        enumerable: true,
        get: () => this.myValue  // ***
      })
    }
  }
}

箭头函数没有自己的this,它们在定义它们的范围内关闭 this,就像它们是变量一样正在关闭。上面的setGlobalObject与此ES2015之前的功能基本相同:

// Pre-ES2015 example for comparison
MyClass.prototype.setGlobalObject = function setGlobalObject() {
  var obj = this;                              // ***
  if (typeof window !== "undefined") {
    Object.defineProperty(window, this.globalVarName, {
      configurable: false,
      enumerable: true,
      get: function() { return obj.myValue; }  // ***
    })
  }
};

(箭头函数也没有自己的arguments对象new.targetsuper。)