Javascript Object.defineProperty,get";这";从班级内部,而不是;“窗口”;

Javascript Object.defineProperty,get";这";从班级内部,而不是;“窗口”;,javascript,Javascript,简而言之,我试图在窗口中定义一个变量,它与类中的myValue保持同步。因此,类中的window.myGlobalVarName应始终等于myValue 我正在使用Object.defineProperty试图阻止变量在窗口中被重新赋值 但是,每当调用get()时,this是类中的窗口对象,而不是this。我是不是漏掉了什么明显的东西?有很多使用get()在类中使用this返回值的示例-我的做法有什么不同 class-MyClass{ 构造函数(){ this.myValue=1 this.gl

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

我正在使用
Object.defineProperty
试图阻止变量在
窗口中被重新赋值

但是,每当调用
get()
时,
this
是类中的
窗口
对象,而不是
this
。我是不是漏掉了什么明显的东西?有很多使用
get()
在类中使用
this
返回值的示例-我的做法有什么不同

class-MyClass{
构造函数(){
this.myValue=1
this.globalVarName=“myGlobalVarName”
this.setGlobalObject()
}
setGlobalObject(){
如果(窗口类型!=“未定义”){
Object.defineProperty(窗口,this.globalVarName{
可配置:false,
可枚举:正确,
get(){return this.myValue}/“this”实际上是“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
      })
    }
  }
但是,每当调用
get()
时,
this
是类中的窗口对象,而不是
this

这就是大多数函数和方法在JavaScript中的工作方式,
这个
是由它们的调用方式设置的,而不是它们的定义位置。详情请参阅对的答复。您的
get
函数是相同的,因为它是一个传统函数(使用方法语法编写)

要从定义函数的位置获取此
,请使用:

箭头函数没有自己的
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; }  // ***
    })
  }
};

(箭头函数也没有自己的
参数
对象、
new.target
super

但是,如果有多个类实例使用相同的名称作为全局变量,该怎么办?
对象.defineProperty
调用将抛出。构造函数(无论是用旧方法还是通过
class
)创建的)主要用于创建类似对象的工厂。如果您只需要一个单例对象,可以直接创建它。(另一方面:最好避免使用globals,这一点现在要容易得多,这要归功于现代浏览器支持的适当模块以及Webpack和RollupJS之类的捆绑包,它们可以为较旧的浏览器创建捆绑包。)很好的观察,在我的实际代码中,我将其包装在try/catch中,还要检查变量是否已经定义-我只是省略了这一点,以保持代码示例更清晰。感谢您的澄清和解释。:)
// 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; }  // ***
    })
  }
};