新的变量的声明方式 let

本文介绍了ES6中`let`关键字声明变量带来的变化,包括它不属于顶层对象window、不允许重复声明、不存在变量提升以及引入的块级作用域和暂时性死区概念。讨论了不使用`var`可能导致的全局污染问题,并通过示例展示了`let`如何解决这些问题。最后提出了使用闭包和直接使用`let`声明变量来避免异步执行中的变量共享问题。
摘要由CSDN通过智能技术生成

ES6 之前的变量声明方式:

在 ES5 中写 var 和 不写 var 区别是什么?

  • 使用 var 是在当前的作用域内声明一个变量
  • 在函数中声明就是函数中的作用域变量
  • 在全局声明就是全局作用域变量
  • 不写 var 就是在 window 这个这个全局对象上定义一个属性

如何证明 不写 var 就是在全局对象 window 上增加了一个属性呢??

通过 函数 delete 方法
delete 的作用就是用于删除对象上的属性 => 注意也只能用于删除对象上的属性 并不能够删除变量

var a = 5
console.log(a)  => 5
delete a
console.log(a) => 5
console.log(window.a) => 5
b = 6
console.log(b) => 6
delete b
console.log(b) // 当前的b已经被删除掉了 报错
console.log(window.b) // undefined

总结 写 【var 就是一个变量 不写 var 就是浏览器顶层对象 window 上的一个属性】
方法 delete 可以删除对象上的属性

window.a 和 window.b 都能够输出内容是因为 js 早期的作者将 Window 顶层对象和 全局变量做了挂钩 (现在多数人都以为这是js var 变量设计的败笔)=> 所以我们使用 let 声明变量就可以很好的解决这个问题

【不推荐在开发项目的时候将 变量挂载在全局对象 window 上 这样会污染全局对象 window】

let aa = 5
console.log(aa) // 5
console.log(window.aa) // undefined

let 声明变量的优点:

  • 不属于顶层对象 window
  • 不允许重复声明 重复声明会报错
  • 不存在变量提升
  • 暂时性死区
  • 块级作用域

优点解释:

· 暂时性死区

【暂时性死区 => 防止变量在声明之前使用变量】

var aaa = 5
if (true) {
	aaa = 6
	let aaa // Cannot access 'aaa' before initialization
}

【这种就会报错 因为在使用的时候还没有声明 这个也是暂时性死区】

function foo(a = b, b = 2) {
	console.log(a, b)
}
foo()

【这里也会报错 因为在调用函数的时候 b 未初始化 暂时性死区】

function foo(a = b, b = 2) {
	console.log(a, b)
}
foo()

【这个先声明在使用的就没有问题】

function foo(a = 2, b = a) {
    console.log(a, b)
}

· 块级作用域

块级作用域: 【在 es5 变量的声明中只有全局作用域和函数作用域 并没有全局作用域的概念 {} 内就是块级作用域】
{} 中定义的变量只能在 {} 中使用出了这个范围就不能使用了

看看 ES5 中没有块级作用域引发的后果

for (var i = 0, i < 3; i++) {
    console.log('循环内:' + i)
}
console.log('循环外' + i) // 最终的结果 i = 3
if (false) {
   var a = 10
}
console.log(a) // undefined

ES6 中存在块级作用域

for (let i = 0, i < 3; i++) {
    console.log('循环内:' + i)
}
console.log('循环外' + i) // 最终的结果 undefined
if (false) {
   var a = 10
}
console.log(a) // 报错

【 ES6 中 块级作用域必须存在 {} 否则 js 引擎就会认为不存在块级作用域 => 报错】

细微差别:

 if (true) var a = 10 // => var 声明变量是可以的 => var 会有变量的提升
 if (true) let a = 10 // => let 声明变量就会报错 => js 引擎认为不存在块级作用域 => 无法声明变量 =>  报错

牛刀小试:

// 考验题
for(var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i) // 3 3 3
    }, 1000)
}

这里输出的结果是 3个3

解释:
在 js 中 setTimeout 定时器是一个异步函数 异步函数的执行会等待同步函数的执行完成 当 for 循环执行完成的时候 才开始异步的 函数执行 所以 会输出 3 个 3

提出挑战 如何才能按照 0 1 2 的方式输出 结果值呢??

方式1: 通过 闭包的方式
for(var i = 0; i < 3; i++) {
	(function(j) {
		setTImeout(function() {
			console.log(j)
		})
	})(i)
}
方式2: 在原来代码的基础上直接使用 let 声明 变量 i 即可

在 编译代码的时候自动将代码编译成 闭包的方式 锁住 变量 i

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值