窗口上的Javascript getters / setters

时间:2013-06-22 12:23:05

标签: javascript

为什么以下命令会在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';
    },
});

1 个答案:

答案 0 :(得分:2)

只写

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