zoukankan      html  css  js  c++  java
  • let const

    let 和 const 命令

    1. let命令

    基础使用

    let声明的变量只在它所在的代码块有效。

    var a = [];
    for (let i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 6
    

    上面代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量.

    另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域

    不存在变量提升

    console.log(bar); // 报错ReferenceError
    let bar = 2;
    

    暂时性死区 (temporal dead zone,简称 TDZ)

    只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

    var tmp = 123;
    
    if (true) {
      // TDZ开始
      tmp = 'abc'; // ReferenceError
      console.log(tmp); // ReferenceError
    
      let tmp; // TDZ结束
      console.log(tmp); // undefined
    
      tmp = 123;
      console.log(tmp); // 123
    }
    

    使用let和const命令声明变量之前,该变量都是不可用的,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错.

    不允许重复声明

    let不允许在相同作用域内,重复声明同一个变量。

    function func(arg) {
      let arg; // 报错
    }
    
    function func(arg) {
      {
        let arg; // 不报错
      }
    }
    

    2.块级作用域

    ES6 允许块级作用域的任意嵌套

    1. 外层作用域无法读取内层作用域的变量
    2. 内层作用域可以定义外层作用域的同名变量
    3. 块级作用域的出现,实际上使得立即执行(匿名)函数不再必要了。

    块级作用域内声明的函数,行为类似于var声明的变量。

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

    ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。

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

    根据这三条规则,在浏览器的ES6环境中,块级作用域内声明的函数,行为类似于var声明的变量。

    function f() { console.log('I am outside!'); }
    (function () {
      if (false) {
        // 重复声明一次函数f
        function f() { console.log('I am inside!'); }
      }
      f();
    }());
    
    /** ES5 环境 **/
    function f() { console.log('I am outside!'); }
    (function () {
      function f() { console.log('I am inside!'); }
      if (false) {
      }
      f();
    }());
    
    /** 浏览器的 ES6 环境 **/
    function f() { console.log('I am outside!'); }
    (function () {
      var f = undefined;
      if (false) {
        function f() { console.log('I am inside!'); }
      }
      f();
    }());
    // Uncaught TypeError: f is not a function
    

    ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。

    // 报错
    '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;
    };
    //变量x会得到整个块级作用域的返回值(t * t + 1)
    

    3.const 命令

    基本用法

    1. 一旦声明,常量的值就不能改变。

      const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化

      本质:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。引用类型数据结构不可变,但内部值可变。
    2. const的作用域与let命令相同:

      只在声明所在的块级作用域内有效。

    3. const命令声明的常量也是不提升,同样存在暂时性死区

      只能在声明的位置后面使用。

    4. const声明的常量,也与let一样不可重复声明

      用let声明过的变量,也不可在用const声明

    如果真的想将对象冻结,应该使用Object.freeze方法

    const foo = Object.freeze({});
    
    // 常规模式时,下面一行不起作用;
    // 严格模式时,该行会报错
    foo.prop = 123;
    

    除了将对象本身冻结,对象的属性(也可能是对象)也应该冻结。下面是一个将对象彻底冻结的函数。

    var constantize = (obj) => {
      Object.freeze(obj);
      Object.keys(obj).forEach( (key, i) => {
        if ( typeof obj[key] === 'object' ) {
          constantize( obj[key] );
        }
      });
    };
    

    ES6 声明变量的六种方法:
    var,functionlet,const,import,class


    本文来源个人对 阮一峰es6 总结,以供今后查阅。

  • 相关阅读:
    【数据库摘要】6_Sql_Inner_Join
    C# 实体类序列化与反序列化一 (XmlSerializer)
    MBProgressHUD 显示方向异常
    回溯算法
    Linux下Tomcat VM參数改动
    053第85题
    让你提前认识软件开发(26):数据库脚本的凝视
    可穿戴设备,或许无屏交互才是终极需求!
    Tomcat载入两次问题
    python字典构造函数dict(mapping)解析
  • 原文地址:https://www.cnblogs.com/topyang/p/11392880.html
Copyright © 2011-2022 走看看