码迷,mamicode.com
首页 > 其他好文 > 详细

ES6中的let

时间:2020-05-04 21:00:39      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:function   def   防止   提升   访问   for   been   ref   引擎   

一、没有声明提升

var有声明提升。

用let来声明变量时,不会将声明提升到最顶部。

console.log(val); // 0
var val = 0;

console.log(a); // Cannot access ‘a‘ before initialization
let a = 1;

因此,当我们使用let来声明变量时,一定要先声明再使用
注意: let声明的变量不会被挂载到window对象上。

let a = 1;
console.log(a); // 1
console.log(window.a); // undefined

二、暂时性死区(块级作用域)

var不存在块级作用域,只有全局作用域和函数作用域。

ES6中存在块级作用域,let仅在代码块内有效。(用大括号括起来的区域就是代码块,引擎会自动识别它。)

{
    var val = 0;
    let a = 1;
    console.log(a); // 1 (在内部可以被访问到)
}
console.log(val); // 0
console.log(a); // ReferenceError: a is not defined (到了外部就不存在了)

这和立即执行函数有异曲同工之妙,达到了保护私有变量,防止污染全局的作用。

(function() {
    var a = 1;
    console.log(a); // 1
})();
console.log(a); // ReferenceError: a is not defined

三、不允许重复声明变量

var可以声明多次。

在同一作用域中,let只能声明一次

let a = 1;
let a = 5;
console.log(a); // SyntaxError: Identifier ‘a‘ has already been declared

四、for循环计数器

一个问题

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

技术图片

运行一下结果是10个10。为什么呢?
第一,var声明的i可以在全局访问到,因此可能会出现覆盖现象。
第二,for循环内的计数器是异步执行的。
综合以上两点,1秒后执行10个setTimeout函数,因为i是定义在全局作用域上的,因此,变量i早就被覆盖成了10。
于是打印出10个10。

解决方案一:立即执行函数

解决问题之前,我们分析到问题的关键是i作为全局变量被污染(覆盖),这才导致了结果出现误差。
那么解决这种问题,我们首先想到的就是立即执行函数(IIFE)。

立即执行函数也叫自执行函数,它的作用就是封装私有变量,防止全局变量受污染。

for(var i = 0; i < 10; i++) {
    (function(j){
        setTimeout(function() {
            console.log(j);
        }, 1000);
    })(i);
}

技术图片

解决方案二:let

因为let只在代码块内有效,因此使用let就避免了变量污染的问题。

for(let i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

技术图片

ES6中的let

标签:function   def   防止   提升   访问   for   been   ref   引擎   

原文地址:https://www.cnblogs.com/buildnewhomeland/p/12828074.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!