ECMAScript6-新的变量声明方式let几大优点

一、let相关特性
1. let 声明的全局变量不是全局对象window的属性
  • 再说这个之前先了解下ES5之前的声明方式

    • 在ES5中写var和不写var区别
    • 使用 var 表示是在当前的作用域内声明一个变量
      • 如果是在函数内声明就是函数中的作用域变量
      • 如果是在函数外就是全局作用域变量
    • 如果不写 var js在编译的时候会在 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
      

    注意这边的window.a 和 window.b 都能够输出内容是因为 js 早期的作者将 window 顶层对象和 全局变量进行了挂钩 (也是败笔之一,很容易污染window对象)=> 使用 let 声明变量就可以很好的解决这个问题

    let aa = 5
    console.log(aa) // 5
    console.log(window.aa) // undefined
    
2. 用let定义变量不允许重复声明
let a = 6
let a = 7	
// 这种的声明是不被允许的 会报 Identifier 'a' has already been declared  
3. let声明的变量不存在变量提升
// 使用var定义 具备变量提升
console.log(a)  => undefined
var a = 5

等价于
var a
console.log(a)
a = 5

// 使用let
console.log(a) => Cannot access 'a' before initialization at xxx.js 
let a = 5
4. let声明的变量具有暂时性死区[Temporal Dead Zone] 简称TDZ

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

var a = 5
if (true) {
	a = 6
	let a // Cannot access 'a' before initialization 却没有报错
}

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

function foo(a = b, b = 2) {  // Cannot access 'b' before initialization
	console.log(a, b)
}
foo()

【改成先声明再使用的就没有问题】

function foo(a = 2, b = a) {
    console.log(a, b)
}
5. let 声明的变量拥有块级作用域

【在 es5 变量的声明中只有全局作用域和函数作用域 并没有块级作用域的概念 {} 内就是块级作用域】
比如:

for (var i = 0; i < 3; i++) {
    console.log('循环内:' + i) // 0 1 2
}
console.log('循环外' + i) // 最终的结果 i = 3

--------------------------------------------

if (false) {
   var a = 10
}
console.log(a) // undefined

使用let

for (let i = 0; i < 3; i++) {
   console.log('循环内:' + i)
}
console.log("循环外" + i)  // i is not defined

// 以下两者细微差距
// var 声明变量是可以的 => var 会有变量的提升
if (true) var a = 10 
// let 声明变量就会报错 => js 引擎认为不存在块级作用域 => 无法声明变量 =>  报错
if (true) let a = 5; //  Lexical declaration cannot appear in a single-statement context

案例:

// 要求输出0 1 2
for(var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i) 
    }, 1000)
}
// 上面的结果输出的是 3 3 3
// setTimeout是一个定时器,属于异步函数,异步函数的执行会等待同步函数的执行完成,当for循环执行完成的时候,才开始异步的函数执行 所以会输出3个3

// 改造方式一:闭包,通过将i传进去,锁住i
for(var i = 0; i < 3; i++) {
	(function(j) {
		setTimeout(function() {
			console.log(j)
		})
	})(i)
}
// 方式二:使用let
for(let i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i) 
    }, 1000)
}

下一篇:ECMAScript6-新的常量声明方式const几大优点

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值