小心ie 下变量申明

看代码说话吧

<script type="text/javascript">
	window.abc = 'i am abc';
</script>
<script>
	var abc = abc || 'abc from another world';
	console.log(abc);
</script>

看这个简单的代码, 看 abc 的结果, 大家都会说打印出来就是 ‘i am abc’, 没错,在chrome,firefox下是这样的,
正如标题所说的一样, 在ie 下就不是这个了,就是 来自另外一个世界的abc了。

开始的时候还以为是变量申明提升(hoisting)的原因,js中是这样的:
用var 申明变量, js 引擎会把变量申明放到当前作用域最开始的地方。
如 var abc = ‘abc’; 就会变成
var abc;
abc = ‘abc’;

把代码改成:

<script type="text/javascript">
	var abc = 'i am abc';  // 同一级的变量申明不会互相覆盖
</script>
<script>
	var abc;  // 同一级的变量申明不会互相覆盖
	abc = abc || 'abc from another world';
	console.log(abc);
</script>

ie 下变成了输出 i am abc

我看了一下不同申明变量的时候,ie 的变量情况:

<script type=”text/javascript”>
window.abc = ‘i am abc’;
</script>

<script type=”text/javascript”>
var abc = ‘i am abc’; // 或者 abc= ‘i am abc’;
</script>

哦, 原来是window对象和 js全局对象的区别
window对象是js全局对象的一个对象。js 全局对象包括window,Array等对象。
在window 下或者js 全局对象下的申明一个属性, 两个对象下都可以获得 如 window.abc = ‘ddd’; 可以用window.abc 或者 abc 访问到这个变量。
在全局对象下申明一个属性, 在全局对象下申明一个属性, 在window 下就有了,就是这里讨论的情况了。
用申明赋值 var abc = ‘i am abc’; 全局和window都有abc了。

在这个问题中, 用window.abc 申明变量, 在第二个script中 var abc; 是window.abc 和 abc 都变成 undefined 了。
在执行abc = abc || ‘abc from another world’, 就出来了我们不希望看到的结果了。

在chrome 下看赋值语句window.abc = ‘i am abc’ , global 和 window 下都有 abc 和值了, 再次var abc 的时候,这个语句就被忽略了。

这里在一个html 中容易看出问题, 实际开发经常是这样的情况, html 中包含两个js , js 中分别的申明方式不一样:

<script src=”s1.js”></script>
<script src=”s2.js”></script>

//s1.js
(function() {
	window.jquery = 'jquery1';
})();

//s2.js
var jquery = jquery || 'jquery2';

在s2.js 就报错了。

Tags:

发表评论

电子邮件地址不会被公开。 必填项已用*标注