• ES6中的let关键字,有什么用呢?


    来吧,开始本节的学习!

    ES6 给开发者带来很多令人激动的特性,其中let关键字就是其中之一。

    那么,let关键字是什么东西?

    let 的用途

    我们回想一下,我们平时在写代码的时候,用var来声明一个变量,除此之外,好像也没用其他的关键字了,不管我们声明的是字符串类型、数组类型还是数字类型等,都用一个var 搞掂(因为JavaScript拥有动态类型),很方便。但现在,ES6告诉你,除了var,不妨试试用let来声明变量试试看。

    咦,这么说,let关键字是用了声明变量的咯?是的,let的用途就是用来声明变量的。

    那么,let关键字是什么东西?

    好端端的用var声明就可以了,为什么要用新的let关键字来声明啊?难道用var有什么不足的地方吗?是的,还真有。

    用 var 的不足之处

    不足一

    来,我们看一段简短的代码:

     
    
    var arr = [ ];
    
    for(var i=0;  i<10;  i++){
        arr [i] = function(){
             alert(i)
        }
    }
    arr [8](); //结果:10

    看代码,不难猜测代码的意图是想给数组a的元素赋值,每一个元素是一个函数,运行后弹出相对应的数字,比如:运行arr[8]();想alert出一个数字8,运行arr[1](); 想alert出一个数字1,依次类推。但是结果并不是我们预想的那样。运行后实际弹出的是10;不管你运行的是arr[8]还是arr[5],或者是数组内的其他元素,都是alert出一个数字:10。但这并不是我们想要的(不要说你故意这么写的,就是想弹出10就好了),为什么是10呢(往下读,有解释)?至少目前我们可以知道了这是var不足的地方。

    那么let能解决这个问题吗?ES6说:能啊,不信你试试看!

    用let替换var后,我们再看看:

    var arr = [ ];
    for(let i=0;  i<10;  i++){
        arr[i] = function(){
             alert(i)
        }
    }
    arr[8](); //结果:8

    对比一下两段代码,唯一的不同之处就是循环的时候初始化变量 i 是使用let,而不是用var,运行arr[8]()后确实弹出了数字8;如果运行的是arr[3](),就会弹出数字3;这才是我们的本意啊,总算实现了,感谢上帝,感谢ES6,感谢let关键字!

    为什么用let就可以,用var就跑偏了呢?这是因为let声明的变量仅仅在自己的块级作用域起作用,出了这个块级作用域就不起作用。就好比,小明在国内考的“高级程序员”证,去到国外应聘,别人就不承认你的文凭了,小明只能乖乖待在国内持证上岗。而let声明的变量也一样,出不了自己的块级作用域。

    那么,什么是块级作用域,怎么才算一个块级作用域?

    任何一对花括号(这玩意:{ })中的语句都属于一个块,在花括号里面用let定义的所有变量在花括号外都是不可见的,我们称之为块级作用域。

    怪不得小明的证件去到美国没法使用了,人家认为它的证件“不可见“,就是没这回事,不承认你的证。回到代码中,for循环含有有{ },也就是含有了块级作用域,每个变量 i 都只是在自己的作用域起作用,例如:第10次循环中的 i 的值不会影响到到第9次循环。

    如果用var声明的变量,就不是这种情况了,i 的值会影响到各个块里面的 i,等循环完后 i 等于10,所有块的i都变成了10了。这就是为什么第一段代码运行后会弹出数字10了,这并不是我们想要的。

    就好比小明陆陆续续去了10个国家玩,每到一个国家都给自己弄了一个不同的身份,但是小明被告知以后只能用在第10个国家取得的那个身份,那么之前9个国家认识小明的朋友都会不认识他的,小明当场就懵逼了。

    不足二

    用var 声明变量的时候会出现“变量提升“的现象。
    “ 变量提升“是什么鬼?新概念第一次听?前端君快来解释一下!

    再看一段简短的代码:

    var a = 1;
    (function(){
       alert(a);
       var a = 2;
    })();//结果:undefined

    初学者可能认为:代码一开始已经定义了变量a,值为1,相当于全局变量,代码运行的时候会先弹出这个全局变量a的值:1;然后再重新给a赋值为2;可偏偏又事与愿违,心好累啊,它会告诉你结果是undefined; undefined就是未定义啊,为什么会是未定义呢?

    var a = 1;
    (function(){
       var a;
       alert(a);
       a = 2;
    })();

    对比一下两段简短的代码:var a = 2; 这句代码被拆分成两部分:声明var a ; 和 定义a = 2;而声明部分被提升(看到了吗?提升两个字出现了)到了代码块的前面,运行的时候自己挪到前面了,这就是“变量提升“,结果就是:先执行声明,接着就执行alert(a);变量a只是声明还没定义,就弹出了undefined了。

    所以,归根结底就是“变量提升“在作怪。这就是var的又一大不足之处。那么,用let关键字在代码块就不会被提升了吗?是的,不提升了。

    如果你用let这样重写刚刚那段代码的话:

    var a = 1;
    (function(){
       alert(a);
       let a = 2;
    })();   // 结果:报错a未定义

    用let关键字来定义a;这样a在代码块内就不会提升了。那为什么又报错了呢,因为用let声明的变量,在其块级作用域内是封闭的,是不会受到外面的全局变量a影响的,并且要先声明再使用,所以a的值即不是1(因为不受外面的影响),也不是undefined(因为先声明后使用),更不是2,未声明定义就使用,只有报错啦。

    用let关键字也算是提醒我们,平时记得先声明定义再使用的好习惯。

    光是var的不足就讲了这么长的篇幅,希望没把你们闷到,我尽量用一些生活的例子来打比方,如果你能能坚持看到这里很不错了,还有一点,再坚持一下。

    这么说,let确实能弥补一些var的不足之处。那么使用let的时候还有什么要注意的吗?有的!

    注意1:同一个块级作用域内,不允许重复声明同一个变量。

    错误示范一:

    {
      var a =1;
      let a =2;  //报错,因为a已经用var声明过
    }
     

    错误示范二:

    {
      let a =1;
      let a= 2; //还是报错,a已经用let声明过。
    }
     

    注意2:函数内不能用let重新声明函数的参数

    错误示范:

    function say(word){
        let word = 'hello Jack';  //报错:用let重新声明word参数
       alert(word)
    }
    say('hello Lili');

    say()函数内用let重新声明了word这个参数,会报错的,千万别这么干。

    关于ES6新增的let关键字,前端君就讲述这么多,毕竟涉及到代码,需要集中精力来看,能坚持到看到这里同学,我要谢谢你们,说明这一节写得还算易懂!

    本节总结

    总结:用let声明变量只在块级作用域起作用,适合在for循环使用,也不会出现变量提升现象。同一个代码块内,不可重复声明的相同变量,不可重复声明函数内的参数。

    更多前端学习内容文章干货请关注我的专栏(不断更新)

    阿里名厂标准web前端高级工程师教程目录大全,从基础到进阶,看完保证您的薪资上升一个台阶

    在这里我给大家准备了很多的学习资料

    其实你与阿里工程师的差距只差这些东西

  • 相关阅读:
    最简单的UDP程序
    最简单的TCP程序
    一道面试题的分析
    JDK5新特性:可变参数方法
    文件IO流总结
    集合使用的总结
    双列集合Map的嵌套遍历
    集合HashSet的使用
    集合TreeSet的使用
    用LinkedList模拟Stack功能
  • 原文地址:https://www.cnblogs.com/coderhf/p/12781996.html
Copyright © 2020-2023  润新知