全局JSON变量覆盖

时间:2012-05-02 18:23:42

标签: javascript json scope

我必须在我的项目中使用json2.js,因为浏览器(IE8)JSON对象不可用于将字符串解析为JSON。

我遇到了json2.js并对变量声明产生了疑问。

A JSON global variable is declared in json2.js like

var JSON;
if(!JSON){
    JSON={};
}

声明var JSON;对全局JSON对象有什么影响。 我希望声明应该覆盖任何浏览器(IE8 / IE7)中的全局JSON对象。 但令我惊讶的是,当全局对象可用时,它不会覆盖。 只有变量定义/启动才会覆盖全局变量? 请澄清。

4 个答案:

答案 0 :(得分:3)

var关键字确保封闭函数中有一个变量,或者在窗口中(如此处),但它不会初始化一个变量。

事实上,订单并没有真正影响。

以此代码为例:

a = 3;
var a;
alert(a);

警告“3”。

因此,您显示的代码中的var声明只是确保测试中不会出现错误,并且不会删除现有值。

最好记住这一点,因为javascript中的常见错误是在函数中有多个var声明,并且在var声明之前设置的值会感到惊讶。以此为例运行:

if (true) {
    ​a = 3;
}
// lot of code, at a different level
if (true) {
    var a;
    if (433/43==3) a=true;
    if (a) alert('should not happen');
};
​

是的,var附加到函数,而不是块...

答案 1 :(得分:3)

对于每个变量声明(不是初始化!)。发生以下情况(section #10.5):

  

8。对于代码中的每个 VariableDeclaration VariableDeclarationNoIn d ,在源文本顺序中执行

     
      
  1. dn 成为 d 中的标识符
  2.   
  3. varAlreadyDeclared 成为调用 env的 HasBinding具体方法传递 dn 作为参数的结果。
  4.   
  5. 如果 varAlreadyDeclared false ,那么   
        
    1. 调用 env的 CreateMutableBinding具体方法,将 dn configurableBindings 作为参数传递。
    2.   
    3. 调用 env的 SetMutableBinding具体方法,将 dn undefined strict 作为参数传递。
    4.   
  6.   

因此,您会看到,只要遇到var x,就会测试环境中是否已存在名为x的变量。如果是,则忽略它,但如果没有,则声明变量并使用undefined进行初始化。

由于代码在全局范围内运行,因此它会测试JSON是否存在于全局范围内。因此,如果JSON已经存在,则会忽略var JSON;


关于测试/解释此行为的一些想法:

我不知道在JavaScript执行中的哪一点创建了全局对象,但我假设在评估所有其他脚本之前。这意味着,JSON存在且在任何变量声明之前具有值,如果包含两个脚本,则只能模拟(我猜也可以内联,它们会在另一个之后进行评估)。

尝试:

// script1.js
var foo = 'bar';

// script2.js
var foo;
if(!foo) {
    foo = 'baz';
}
alert(foo);

// include script2.js after script1.js

结果是什么? (cheaters look here)。


每当您在一个脚本文件中时,所有变量声明都会被提升到顶部。所以,如果你有

var foo = 'bar';
var foo;
if(!foo) {
    foo = 'baz';
}

脚本实际执行为:

var foo;
var foo;
foo = 'bar';
if(!foo) {
    foo = 'baz';
}

你实际上无法测试第二个var foo;是否会覆盖第一个,因为此时它还没有值。因此,这不是证明上述行为的好例子。

答案 2 :(得分:0)

它可能不是您的选择,但也可以将IE8设置为兼容模式以获取本机JSON对象:

// in your preinit page event
Response.AddHeader("X-UA-Compatible", "IE=8");

另一个选项是仅在JSON变量不存在时才创建它:

var JSON = JSON || {};

答案 3 :(得分:-1)

如果您在执行该代码块时处于全局范围内,则var JSON会将全局JSON对象覆盖为未定义。

如果你在任何其他范围内(比如在一个函数内),那么就没有效果了。