es6之let

作者: 一枚靠脸吃饭的程序员 | 来源:发表于2017-09-08 15:41 被阅读0次

    layout: post
    title: es6之let
    date: 2017-09-08 14:22:42
    tags: 学习


    概述

    在写上一篇文章,关于cookie的操作时有一个demo,涉及到一个作用域的问题,实验了一下,然后又归纳小结了一波,主要还是参考阮大的es6入门,也算是面试经常问的问题,let和var的区别,之前都会回答块级作用域,具体一点的,申明提前,暂时性死区的都会大概提一提。想想还是好好梳理一下好了。

    不存在变量提升

    变量提升可以换一个词,在代码编译阶段做的申明提前操作。
    随便看几个demo,和var的对比很容易看出来

    console.log(a) // undefined
    var a = 'var'
    
    console.log(b) // 报错,b is not defined
    let b = 'let'
    

    那么再看一个demo,涉及到作用域的

    var globalObj = {a:1}
    var func = function() {
        console.log(globalObj)  //undefined
        globalObj.b = 2         //报错,cannot 'b' of undefined
        var globalObj = asdasd
    }
    console.log(globalObj)
    

    虽然globalObj是全局作用域下,func也在里面,但是在内部局部的globalObj优先级高,虽然globalObj在内层是undefined也不影响。
    今天在看犀牛书关于cookie操作的时候有个demo就有这个问题p591

    暂时性死区

    ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
    继续用上一个demo,换成es6的版本,报的错不一样。
    这么做个人感觉挺好,也算是一种规范,以前变量申明之前是可以用这个变量的,值是undefined,这样造成了很多意想不到的情况。
    tips:typeOf方法也有可能报错啦

    let globalObj = {a:1}
    const func = () => {
        console.log(globalObj)  //Identifier 'globalObj' has already been declared
        globalObj.b = 2
        let globalObj = asdasd
    }
    console.log(globalObj)
    

    不允许重复申明

    var a = 1
    var a = 2
    let b = 3
    let b = 4 // b报错, b has been declared
    

    tip: 函数的形参也可以理解为申明了局部变量,所以也不能再次申明

    块级作用域

    先看一下函数作用域不好的地方

    var tmp = new Date();
    function f() {
      console.log(tmp);
      if (false) {
        var tmp = 'hello world';
      }
    }
    f(); // undefined
    

    阮大给的这个demo挺nice的,f调用的时候本来是想tmp没有暴露到f的作用域下,引擎对tmp执行RHS查询,找到上一层作用域的tmp,但是if条件里面的逻辑没有形成作用域,tem在f函数中为局部变量。

    var s = 'hello';
    
    for (var i = 0; i < s.length; i++) {
      console.log(s[i]);
    }
    
    console.log(i); // 5
    

    初学者写这种代码都没注意到内存泄露等问题,暴露过多的全局变量肯定是不好的。

    相关文章

      网友评论

          本文标题:es6之let

          本文链接:https://www.haomeiwen.com/subject/nftnjxtx.html