1.允许重复声明,导致变量被覆盖。看如下代码:
var a = 1;
function prinf(){
console.log(a);
}
var a = 2;
prinf();
结果输出:
这里假设你var a = 2前面还有上万行代码,那么你调用prinf函数的时候,是想打印之前的a,但是你忘记之前声明的变量和几万行代码后面的a是同名的,导致后面声明的a覆盖了之前的a.
2.变量提升:闭包问题,怪异的数据访问.
看如下代码:
if(Math.random() > 0.5){
var a = "abc";
console.log(a);
}else{
console.log(a);
}
console.log(a);
输出结果:
由于变量提升问题,这段代码是不会报错的,但是逻辑是有问题的。
闭包问题:看如下代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
// 在box里面加入10个按钮,点击每个按钮,打印按钮的编号
var box = document.getElementById("box");
for (var i = 1;i<=10; i++) {
var btn = document.createElement("button");
btn.innerHTML = "按钮"+i;
box.appendChild(btn);
}
</script>
</body>
</html>
页面效果:
然后现在的需求是;点击按钮,输出按钮对应的编号
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
// 在box里面加入10个按钮,点击每个按钮,打印按钮的编号
var box = document.getElementById("box");
for (var i = 1;i<=10; i++) {
var btn = document.createElement("button");
btn.innerHTML = "按钮"+i;
box.appendChild(btn);
btn.onclick = function(){
console.log(i);
}
}
</script>
</body>
</html>
这里打印的结果都是11.我们期望的是打印对应的编号。由于点击事件里面访问的是外部变量,点击事件还没有发生,循环就已经结束了,所以打印的都是11.
解决办法:写很不优雅的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
// 在box里面加入10个按钮,点击每个按钮,打印按钮的编号
var box = document.getElementById("box");
for(var i = 1; i <= 10; i++) {
var btn = document.createElement("button");
btn.innerHTML = "按钮" + i;
box.appendChild(btn);
(function(i) {
btn.onclick = function() {
console.log(i);
}
})(i)
}
</script>
</body>
</html>
3.全局变量挂载到全局对象:全局对象成员污染问题
先看如下代码:
<script type="text/javascript">
var console = "打印";
console.log(console);
</script>
输出结果:
这里console是全局上面的一个对象,但是我们声明的时候将其覆盖了。
4.以上就是js里面使用var声明变量的几个问题。