美文网首页
let和const命令

let和const命令

作者: Kris_lee | 来源:发表于2017-10-25 17:26 被阅读5次

    本文以及之后的文章都是参考
    阮一峰ES6入门
    ,记录下作为笔记。

    let 命令

    块级作用域

    const 命令

    顶层对象的属性

    global对象

    块级作用域

    es5只有全局作用域和函数作用域,没有块级作用域,这样回带来很多不合理的场景。
    • 第一种 内层变量可能会覆盖外层变量。

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

      上面代码的原意是,if代码块的外部使用外层的tmp变量,内部使用内层的tmp变量。但是,函数f执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。

    • 第二种 用来计数的循环变量泄露为全局变量。

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

    上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。

    es6块级作用域

    let实际上为 JavaScript 新增了块级作用域。

    function f1() {
      let n = 5;
      if (true) {
        let n = 10;
      }
      console.log(n); // 5
    }
    

    上面的函数有两个代码块,都声明了变量n,运行后输出5。这表示外层代码块不受内层代码块的影响。如果两次都使用var定义变量n,最后输出的值才是10。

    {{{{
      {let insane = 'Hello World'}
      console.log(insane); // 报错
    }}}};
    
    而块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。

    (敲黑板。这是重点)

        (function func(){
        console.log("this is IIFE");
    }())
    
    {
        let temp = "hello this is es6"
        console.log(temp);
    }
    

    ![es6-1](/Users/air/Desktop/屏幕快照 2017-10-20 下午4.22.36.png)

    块级作用域与函数声明

    ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。

    function f() { console.log('I am outside!'); }
    
    (function () {
      if (false) {
        // 重复声明一次函数f
        function f() { console.log('I am inside!'); }
      }
    
      f();
    }());
    

    上面代码在 ES5 中运行,会得到“I am inside!”,因为在if内声明的函数f会被提升到函数头部,实际运行的代码如下。

    // ES5 环境
    function f() { console.log('I am outside!'); }
    
    (function () {
      function f() { console.log('I am inside!'); }
      if (false) {
      }
      f();
    }());
    

    理论上es6环境下是回得到 outside 。但是在实际运行下,是报错的,TypeError: f is not a function

    为什么呢?

    如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题

    • 允许在块级作用域内声明函数。
    • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
    • 同时,函数声明还会提升到所在的块级作用域的头部。

    上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。

    考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。

    // 函数声明语句
    {
      let a = 'secret';
      function f() {
        return a;
      }
    }
    
    // 函数表达式
    {
      let a = 'secret';
      let f = function () {
        return a;
      };
    }
    

    另外,还有一个需要注意的地方。ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。

    // 不报错
    'use strict';
    if (true) {
      function f() {}
    }
    
    // 报错
    'use strict';
    if (true)
      function f() {}
    

    do表达式

    本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。

    {
      let t = f();
      t = t * t + 1;
    }
    

    上面代码中,块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到t的值,因为块级作用域不返回值,除非t是全局变量。

    现在有一个提案,使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上do,使它变为do表达式。

    let x = do {
      let t = f();
      t * t + 1;
    };
    

    const命令

    const声明一个只读的常量。一旦声明,常量的值就不能改变。

    const PI = 3.1415;
    PI // 3.1415
    
    PI = 3;
    // TypeError: Assignment to constant variable.
    
    
    const foo;
    // SyntaxError: Missing initializer in const declaration
    

    const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

    const的作用域与let命令相同:只在声明所在的块级作用域内有效。

    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

    ES6 声明变量的六种方法

    ES5 只有两种声明变量的方法:var命令和function命令。ES6除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法:import命令和class命令。所以,ES6 一共有6种声明变量的方法。

    相关文章

      网友评论

          本文标题:let和const命令

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