var和let声明变量的问题
使用var声明的变量
1.允许重复的变量声明:导致数据被覆盖
var a = 1;
function print(){
console.log(a);
}
var a = 2;
print();//此时输出的值为2
由于变量提升的问题,当声明a变量后,再次声明一个相同的变量后,原有的变量a会被销毁,而使得此时的a变为2.与我们想输出a=1的意愿相反。
2.变量的提升:怪异的数据访问、闭包问题
if(Math.random() < 0.5){
var a = "abc";
console.log(a);
}else{
console.log(a);
}
输出结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3L1WGJR3-1594895205344)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20200716174753057.png)]
程序的逻辑是:当生成一个随机数<0.5,则声明一个变量a,且值为abc,并打印a;否则打印else中未声明a的值。
实际上,我们应该觉得奇怪:为什么else中的a没有声明,为什么它没有报错?原来是变量提升的问题,使得在执行if语句前,已经声明了一个变量a.
闭包问题:
<div id = "btn"></div>
var divBtn = document.getElementById('btn');
for(var i = 1; i <= 10; i++){
var btn = document.createElement('button');
btn.innerHTML = '按钮' + i;
divBtn.appendChild(btn);
btn.onclick = function () {
console.log(i);
}
}
输出结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gu86wJF3-1594895205348)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20200716180018112.png)]
没错!输出都为11。这是由于闭包问题,这里不多详细讨论这个问题,可参考其它关于闭包问题。
3.全局变量挂载到全局对象:全局对象成员污染问题
var cosole = "abc";
console.log(console);
console是window下的对象,当我们声明为全局变量时,容易修改它的值,使得全局对象的成员的值发生改变。
使用let声明变量
ES6不仅引入let关键字用于解决变量声明的问题,同时引入了块级作用域的概念。
块级作用域:代码执行时遇到的花括号,会创建一个块级作用域,花括号结束,销毁块级作用域。
let a = 123;
{
let a = 456;
console.log(a);//输出为456
}
console.log(a);//输出为123
-
let声明的变量不会挂载到全局对象
let a = 123; console.log(window.a) //输出为undefined
-
let声明的变量,不允许当前的作用域范围内重复声明(在块级作用域中用let定义的变量,在作用域外不能访问)
let a = 21; let a = 12; //检查到,当前作用域(全局作用域)已声明了变量a
-
使用let不会有变量提升,因此,不能在定义let变量之前使用它
if (Math.random() < 0.5) { let a = 123; //定义在当前块级作用域 console.log(a) //当前块级作用域中的a } else { //这是另外一个块级作用域,该作用域中找不到a console.log(a) } console.log(a);
本文是自己学习中学习的笔记,有任何理解错误问题欢迎指出。