小新(bai)前端第一次写文章——关于var和let的使用

124 阅读3分钟

1. var和let的区别

(1). var 和 let 最明显的区别就是作用域的不同let 声明的范围是块作用域, 而 var 声明的范围是函数作用域。 使用 var 操作符定义的变量会成为包含它的函数的局部变量。比如,使用 var 在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁。

function test() {
 var message = "hi"; // 局部变量
}
test();
console.log(message); // 出错!
解决出错:可以直接把函数中的var去掉,由于有变量提升,所以不会报错,直接输出undefined不过不推荐这种做法,难维护,而且如果在严格模式下执行,会抛出ReferenceError错误;平常我们定义经常是放在script标签下,没有函数包含着,但是在全局函数中,所以这种变量属于全局变量。
if (true) {
 let age = 22;
 console.log(age); // 22
}
console.log(age); // 抛出ReferenceError: age 没有定义

(2). let 与 var 的另一个重要的区别,就是 let 声明的变量不会在[作用域]中被提升。JavaScript执行代码是,遇到先调用后面申明的let变量,也会报错ReferenceError。因为没有变量提升,也称为暂时性死区。

// name 会被提升
console.log(name); // undefined
var name = 'Matt';
// age 不会被提升
console.log(age); // ReferenceError:age 没有定义
let age = 26;

2. var和let定义变量时一起使用,需要注意的问题

let 也不允许同一个块作用域中出现冗余声明。这样会导致报错,即使分成两个script标签写也是报错。
var name; 
var name; //可以
let age; 
let age; // SyntaxError;标识符 age 已经声明过了
在不同块级作用域下,let声明同一个变量名不会报错,JavaScript 引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错
var name = 'Nicholas';
console.log(name); // 'Nicholas'
if (true) {
 var name = 'Matt';
 console.log(name); // 'Matt'
}
let age = 31;
console.log(age); // 30
if (true) {
 let age = 22;
 console.log(age); // 26
}
使用let 和 var 声明同一个变量时候,声明冗余报错不会因混用 let 和 var 而受影响。这两个关键字声明的并不是不同类型的变量, 它们只是指出变量在相关作用域如何存在。
var name;
let name; // SyntaxError
let age;
var age; // SyntaxError

3. 在for循环中遇到的问题和需要注意的点

我学习ES6过程中,很多都是用for循环来引出let在其中的作用,以及解决输出的i都是最终值问题,容易产生一个误区——例如在for(var i = 0; i<6; i++) 的循环下,以为都会出现输出的i会都是6情况(有可能只有我个人才觉得),其实不是的
for(var i = 0; i<5; i++) {
            setTimeout(() =>{console.log("setTimeout的i:",i)} ,0) ; //全部输出的是5
            function con() {
                console.log("函数的i",i);
            }
            console.log("直接的j",i); //依次输出0-4
        }
        con() // 输出的是5
        for(let j = 0; j<5; j++) {
            setTimeout(() =>{console.log("setTimeout的j:",j)} ,0) ;//输出的0-4
            function con() {
                console.log("函数的j",j); 
            }
            console.log("直接的j",j); //依次输出是0-4
        }
        con()// 输出的是4
由代码可看出,使用var定义的i变量,并不是在for循环中输出的一定是最终值,分两种情况:第一是顺序执行代码,也就是同步执行,这样输出的对应的是当时i的值;另一种就是异步回调或执行,代码中的setTimeout,由于i是用var定义的,在for里面初始化,属于全局的作用域,此时异步去执行时,调用里面的i已经是最终值。所以不是特殊需求下,一般不能用var定义的变量在for循环中绑定监听事件。

4. 总结

var和let定义变量的相关知识大致就是以上3点,是平常项目会遇到普遍问题,具体的更多细节知识就不过多列举了,如果以上有知识点或解释错误的,欢迎留言,多多指教,谢谢!前端小白第一次写文章,多多支持哈!!!