【问题标题】:Javascript getters/setters on window窗口上的 Javascript getter/setter
【发布时间】:2013-06-22 12:23:04
【问题描述】:

为什么在 firefox 21.0 中会抛出 TypeError?

Object.defineProperty(window,'windowProperty',{
    get: function(){
        return 'windowProperty'
    },

    set: function(val){
        console.log('windowProperty is being set');
    },

    configurable: true,
});

var windowProperty;

但是在不使用 var 的情况下声明 windowProperty 是可行的:

windowProperty;

或者

window.windowProperty;

这种行为也存在于蜘蛛猴中:

var a=1;

Object.defineProperty(this,'a',{
    get: function(){
        return 'a';
    },
});

【问题讨论】:

  • 您在使用哪个浏览器?我在 chrome 和 Firefox 上试过,没有看到 TypeError。
  • 在 IE 中一切正常。你的问题是什么?
  • 更新了,我的问题不是针对ie,而是针对firefox

标签: javascript


【解决方案1】:

只写

windowProperty;

不声明变量。它只是尝试在最近的上下文中返回变量内容,如果找不到,则返回 undefined。这就像没有目标的任务。例如,你也可以写随机文本而不抛出错误:

'Hello, world !';
123456;
undefined;

使用 var 尝试重新定义之前已在代码中定义的属性,因此会出错。

编辑
正如 simonzack 所说,浏览器在重新定义变量时并不总是发送错误。例如:

var test; var test;

不会抛出这个错误(即使这是一个坏主意并且一些 JS 验证器会警告你)。 但是,通过定义 getter 和 setter,浏览器“锁定”了这个属性(以防止冲突,例如,同一属性上的两个不同的 setter)。 糟糕,这是一种误解。

您有什么理由要重新定义变量吗?

编辑 2
考虑到var 声明在defineProperty 之前,它可以增加我的解释的准确性。事实上,当您第一次使用var 声明时,浏览器会将其configurable 状态设置为false,这会阻止对其描述符(See link)进行更改。因此,当您尝试使用 defineProperty 函数更改它时,会导致错误。一个更好看的例子是将代码包装在一个闭包函数中。这样var定义的windowProperty就不一样了,一切正常。

(function () {
    var windowProperty;
    Object.defineProperty(...);
    //It works because the previously defined variable is in the scope of the function and thus is not the same as window.windowProperty.
})();

【讨论】:

  • 根据您的逻辑,var test;var test; 应该会抛出错误,但不会。
  • @simonzack 你说得对,我的回答的第二部分不完整。那是因为您为该属性定义了访问器(getset),所以浏览器“锁定”了它。我会更新我的答案。
  • 如果可配置设置为 false,浏览器实际上只会“锁定”该属性。查看 Mozilla 文档:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。这与“var”有什么关系?
  • 我没有这样说“锁定”。将可配置设置为 true 后,您确实可以替换 get&set 属性或删除此属性,但是当它在这里时,您不能再次定义它。无论如何,你为什么要这样做?看不懂var windowProperty;的用法
  • 我这样做是因为在这种情况下我不确定为什么在这种情况下它的行为与window.windowProperty 不同。而且您的回答还没有解决“重新定义”对 getter/setter 的含义。你能给我参考文档吗?我找不到任何东西。顺便说一句,var windowProperty 实际上是在defineProperty 之前运行的,我认为您没有意识到这一点。
猜你喜欢
  • 2011-01-27
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多