覆盖JavaScript中的全局属性

时间:2013-08-09 15:27:35

标签: javascript scope global

在阅读reply我对链接帖子的评论后,我决定对window对象和全局范围进行测试。我读了一些关于如何引用原始函数的其他问题,例如thisthisthis,但所有这些问题通常都涉及将原始函数存储在另一个变量中或将其包装在匿名函数(单独的命名空间)。

测试代码

var x = ' 0 '; // a global variable

document.body.innerHTML += x;
document.body.innerHTML += window.x;

// setTimeout before overriding
setTimeout(function () {
    document.body.innerHTML += ' 1 ';
}, 500);

// window.setTimeout before overriding
window.setTimeout(function() {
    document.body.innerHTML += ' 2 ';
}, 1000);

// Overriding setTimeout
function setTimeout(f, time) {
    'use strict';
    if (typeof f === 'function') {
        document.body.innerHTML += ' 3 ';
    }
}

// setTimeout after overriding
setTimeout(function () {
    document.body.innerHTML += ' 4 ';
}, 1000);

// window.setTimeout after overriding setTimeout globally
window.setTimeout(function () {
    document.body.innerHTML += ' 5 ';
}, 2000);

// Overriding window.setTimeout
window.setTimeout = function (f, time) {
    'use strict';
    if (typeof f === 'function') {
        document.body.style.backgroundColor = 'orange';
    }
};

// window.setTimeout after overriding
window.setTimeout(function () {
    document.body.innerHTML += ' 6 ';
}, 3000);

jsFiddle。请注意,在小提琴初始化之后,您可能需要点击“运行”以查看延迟。

实验结果

0
undefined
3
3
(page becomes orange) 
2 (after a delay)
5 (after a longer delay)

预期结果

0
0
3
(page becomes orange)
1 (after 500ms)
2 (after 1000ms)
5 (after 2000ms)

有人可以解释为什么我的代码的行为与预期不同吗?

此外,我意识到在浏览器环境之外运行的JavaScript会有所不同,因此出于这个问题的目的,我将在浏览器环境中坚持使用JavaScript应用程序。

1 个答案:

答案 0 :(得分:0)

您在JSFiddle中的代码不在全局范围内运行。这就是在声明和定义window.xundefinedx的原因。

至于本地范围的重新定义。你被允许这样做:

var a;
a = b();
function b() {
    return 5;
}
console.log(a); // 5

您可以在声明和定义之前调用b,因为它已移至顶部。这也称为吊装。

即使你这样做:

function b () {
    return 1;
}
(function () {
    console.log(b()); // 2, not 1
    function b() {
        return 2;
    }
}());

再次,因为吊装。实际执行顺序是:

var b;
b = function () {
    return 1;
}
(function () {
    var b;
    b = function b() {
        return 2;
    }
    console.log(b()); // 2, makes sense
}());