一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
变量声明的问题
ES5之前是通过var声明变量,既然通过var能声明变量,为什么ES6要新增声明变量的方式呢?那么使用var会导致什么问题呢?
允许重复声明变量,导致数据被覆盖。
var a = 1;
function print(){
console.log(a)
}
// ...
var a = 2;
print();//2
当我们书写的代码量较多时,根本就记不清之前声明过哪些变量。一但变量重复,之前写的函数可能就会产生冲突,造成不必要的bug。
变量提升,怪异的数据访问、闭包。
if(Math.random()<0.5){
var a = 'a';
console.log(a);
}else{
// 没有声明也能访问a
console.log(a);
}
console.log(a);
如果随机数小于0.5,则声明变量a,赋值为'a',输出a。
如果随机数不小于0.5,则输出a。
因为变量提升,这段代码其实是有问题的,逻辑就变成了,先声明变量a。由于变量提升,导致了怪异的代码书写。
当我们想要实现一个按钮每次点击输出编号,尝试用var来声明变量。
var body = document.querySelector('body');
for( var i = 1; i <= 10; i++){
var btn = document.createElement('button');
btn.innerHTML = '按钮' + 1;
body.appendChild(btn);
btn.addEventListener('click', function(){
console.log(i)
})
}
每一个按钮点击之后使用同一个变量i,输出11。
var body = document.querySelector('body');
for( var i = 1; i <= 10; i++){
var j = i;
var btn = document.createElement('button');
btn.innerHTML = '按钮' + 1;
body.appendChild(btn);
btn.addEventListener('click', function(){
console.log(j)
})
}
当尝试用变量j来保存i, 我们发现每次输出的却变成了10。
原因是变量j也会提升,这两种情况都导致我们的需求无法实现。
我们为了实现这个需求,不惜写一些丑陋的代码。
var body = document.querySelector('body');
for( var i = 1; i <= 10; i++){
var btn = document.createElement('button');
btn.innerHTML = '按钮' + 1;
body.appendChild(btn);
(function (i) {
btn.addEventListener('click', function(){
console.log(i)
})
})(i)
}
全局变量挂载到全局对象,全局对象成员污染。
当我们写了很多个js文件,在全局对象上就挂载了很多个变量,难免会造成变量冲突问题。
window的成员也会被覆盖,最常见的就是window.name。