我必须在我的项目中使用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对象。
但令我惊讶的是,当全局对象可用时,它不会覆盖。
只有变量定义/启动才会覆盖全局变量?
请澄清。
答案 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 ,在源文本顺序中执行
- 让 dn 成为 d 中的标识符。
- 让 varAlreadyDeclared 成为调用 env的 HasBinding具体方法传递 dn 作为参数的结果。
- 如果 varAlreadyDeclared false ,那么
醇>
- 调用 env的 CreateMutableBinding具体方法,将 dn 和 configurableBindings 作为参数传递。
- 调用 env的 SetMutableBinding具体方法,将 dn , undefined 和 strict 作为参数传递。
因此,您会看到,只要遇到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对象覆盖为未定义。
如果你在任何其他范围内(比如在一个函数内),那么就没有效果了。