1

为什么以下会在 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;

这种行为也出现在 spidermonkey 中:

var a=1;

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

1 回答 1

2

只写

windowProperty;

不声明变量。它只是尝试在最近的上下文中返回变量内容,或者undefined如果找不到它。这就像没有目标的任务。例如,您还可以编写随机文本而不会引发错误:

'Hello, world !';
123456;
undefined;

改用 var 尝试重新定义之前在代码中定义的属性,因此出现错误。

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

var test; var test;

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

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

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

(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.
})();
于 2013-06-22T12:30:33.673 回答