2020-09-22 let 与 var 的区别

147 阅读2分钟

var关键字

  1. var 操作符用来声明一个变量,只是简单的对变量进行赋值,并不能标识变量的类型。
var message = 'hi'
//message是一个占位符,保存了'hi'
  1. 函数内部使用var声明的变量,即全局变量,在函数调用时创建变量并赋值,函数调用结束,变量就会被销毁
function test(){
	var name = "li"
}
console.log(name) //报错
  1. 在函数内部,不适用任何操作符定义的变量是全局变量(不推荐使用,不好维护)。
function test(){
	name = "qq"
}
console.log(name) // qq name为全局变量
  1. 使用var声明的变量,会存在声明提升,提升到他的作用域顶部,并且JS引擎会将重复的声明合并成一个。
function test(){
	console.log(name)
    var name = "ll"
}
test() // undefined

以上代码等价于:

function test(){
	var name;
    console.log(name);
    name = "ll"
}
test()
  1. 使用var声明的变量会挂载到window对象上
var name  = "ll"
console.log(window.nam) // ll
  1. var可以重复声明变量且赋值
var a = '11';
var a = '22';
var a = '33';
console.log(a) // 33
  1. 因为ECMAScript类型是松散类型,不同类型的初始化可以使用一条语句来声明,使用逗号
var a = 'll',
b = 22,
c = false;

let关键字

  1. let操作符声明的变量存在临时性死区,不可以先使用在声明
function test(){
	console.log(name)
    let name = "ll"
}
test()  // 报错Cannot access 'name' before initialization
  1. let会创建块级作用域
if(true){
	let a = "ll"
    console.log(a) // ll
}
console.log(a) // a is not defined
// a 只在if的代码块内有效
  1. let 声明的变量不会挂载到window上,但依旧是全局作用域发生,变量会在页面的生命周期内存在
let a = '222'
console.log(window.a) // undefined
  1. let 不可以重复声明,即使let和var混用也不可以,因为他们不是生命不同类型的变量,只是决定变量的作用域
let a;
let a;

let a;
var a;

var a;
let a;
//以上都会报错
  1. let 可以重复赋值
let a = '111'
a = '222'
console.log(a) // 222

对于for ,let和var对他的影响

  1. for循环定义的迭代变量,使用var声明会渗透到循环体外部
for(var i = 0; i < 5; i++){
}
console.log(i) // 5
  1. for循环定义的迭代变量,使用let声明只在for循环块内部有效
for(let i = 0; i < 5; i++){
}
console.log(i) // i is not defined
  1. 对于以下代码
for(var i = 0; i < 5; i++){
	setTimeout(() => {
		console.log(i)
	},0)
}

打印结果为5,5,5,5,5,因为在退出循环时,迭代变量被保存为退出循环的值5,那么在执行setTimeout打印出的都是5 4. 对于以下代码

for(let i = 0; i < 5; i++){
	setTimeout(() => {
		console.log(i)
	},0)
}

打印出的结果为0,1,2,3,4;因为JS引擎会在后台为每个迭代变量声明一个新的迭代变量,每个setTimeout()都引用的不同的变量实例,所以输出结构就是期望值

以上代码,适用于所有的for风格,包括for...in / for ...of