小例子理解ES6新声明方式let


let是ES6新的变量声明方式,相当于ES5中的var,那么相比于var,let又有什么新特性呢?今天就来聊聊let的特性。

1、let不属于顶层对象window

var声明的变量属于window对象,可以用 window.变量名 调用,但是let声明的变量不属于window对象。下面结合例子来说明一下:
var的例子

var a=5 //var定义该作用域内的全局变量
console.log(window.a)//5 (a是window的变量)
delete a//delete只能删除对象不能删除变量
console.log(a)//5 (a是window的变量不是对象,不能用delete删除)

这里补充另外一种情况是省略了var,赋值给未声明的变量,当执行时会隐式创建全局变量(成为window的对象)

b=6 //b成为window的对象
console.log(b)//6
console.log(window.b)//6
delete b
console.log(window.b)//打印失败 (b是window的对象,可以用delete删除)

接下来该说说let

let a=5
console.log(a)//5
console.log(window.a)//undefined (let声明的变量不属于window)
2、let不可以重复声明

这个很好理解,var可以重复声明变量

var a = 5
var a = 6
console.log(a) // 5

let不可以重复声明变量

let a = 5
let a = 6
// VM131:1 Uncaught SyntaxError: Identifier 'a' has already been declared
//   at <anonymous>:1:1
3、let不存在变量提升

var 声明的变量会在任意代码执行前处理,这意味着在任意地方声明变量都等同于在作用域顶部声明——即声明提升(可以在声明语句之前使用)。

console.log(a)//undefine (打印出undefined而不是报错,可见var存在变量提升)
var a = 5
//相当于
// var a
// console.log(a)
// a=5

function foo(){
    console.log(b)
    var b=5
}
foo()//undefined 
//相当于
//function foo(){
//	var b
//    console.log(b)
//    b=5
//}
//foo()

let声明的变量不存在变量提升。

console.log(a)//报错
let a = 5
console.log(sum(2,3))//报错
let sum=function(x,y){
    return x+y
}

let不存在变量提升的特性,符合ES6的规定的暂时性死区,可以防止变量在声明之前被使用。暂时性死区:

var a=5
if(true){
    a=6
    let a//会报错
}
//大括号{}内即为一个块作用域,作用域内let变量必须先声明才能赋值(使用)

更多关于变量提升建议阅读 (深入理解js中变量提升: https://github.com/creeperyang/blog/issues/16.)

4、块级作用域

常见的作用域分为以下几个类型:

对象类型
window/global全局作用域
function函数作用域/局部作用域
{}块状作用域
this动态作用域

更多关于作用域建议阅读(https://github.com/mqyqingfeng/Blog/issues/3

块级作用域——对比var和let
例一:

//var没有块级作用域
for(var i=0;i<3;i++){
    console.log("循环内:"+i)//0 1 2
}
console.log("循环外:"+i)//3

//let有块级作用域
for(let i=0;i<3;i++){
    console.log("循环内:"+i)//0 1 2
}
console.log("循环外:"+i)//报错

例二:

//var没有块级作用域
if(false){
    var a=5
}
console.log(a)//undefined
//a无块级作用域 a被声明但是取不到5

//let有块级作用域
if(false){
    let a=5
}
console.log(a)//报错 a没有被声明

例三:

//var声明循环变量时出现的问题
for(var i=0;i<3;i++){
    setTimeout(function(){
        console.log(i)//3 3 3
    })
}
//for循环是同步操作,会直接执行三次,有三个setTimeout函数,该函数是异步操作,不会直接执行,会等for循环(主线程)执行完时才统一执行

//此时可以用闭包函数解决
//闭包:内部函数引用外部函数的参数,使外部函数的参数不被释放(是ES5语法)
//(funtion(){})() 匿名函数格式
for(var i=0;i<3;i++){
    (function(j){
        setTimeout(function(){
            console.log(j)//0 1 2
        })
    })(i)
}

//也可以用let解决
 for(let i=0;i<3;i++){
     setTimeout(function(){
         console.log(i)//0 1 2
     })
 }

//经Babel编译后
var _loop = function _loop(i) {
    setTimeout(function () {
      console.log(i); //0 1 2
    });
  };
  
  for (var i = 0; i < 3; i++) {
    _loop(i);
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值