zoukankan      html  css  js  c++  java
  • 2. let和const命令--ES6

    1. let命令

    let 命令不存在变量提升
    let 命令 只在let命令所在的代码块内有效。

    {
      let a = 10;
      var b = 1;
    }
    
    a // ReferenceError: a is not defined.
    b // 1

    特别适合 for 语句

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

    其实对于上面的代码, babel 转码以后变成

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

    for循环还有一个特别之处,就是循环语句部分是一个父作用域,而循环体内部是一个单独的子作用域。

    for (let i = 0; i < 3; i++) {
      let i = 'abc';
      console.log(i);
    }
    // abc
    // abc
    // abc

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

    下面的例子, 由于在代码里 定义了let tmp, 所以会报错

    var tmp = 123;
    
    if (true) {
      tmp = 'abc'; // tmp is not defined
      typeof tmp; // tmp is not defined
      let tmp;
    }

    但是如果直接 typeof 一个不存在的变量 aaa, 则不会报错
    typeof aaa // "undefined"

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

    function f() {
      let a = 10;
      var a = 1;
    }
    f(); // 执行的时候报错
    
    function func(arg) {
      let arg;
    }
    func(2); // 执行的时候报错
    
    function func(arg) {
      {
        let arg; // 不报错
      }
    }
    func(2); // 不报错

    2. 块级作用域

    内层作用域可以定义外层作用域的同名变量。

    {
      let insane = 'Hello World';
      {let insane = 'Hello World'}
    };

    块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。

    // IIFE 写法
    (function () {
      var tmp = 2;
      console.log(tmp);
    }());
    
    // 块级作用域写法
    {
      let tmp = 2;
      console.log(tmp);
    }

    块级作用域与函数声明
    ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
    但是,浏览器 为了兼容以前的旧代码,还是支持在块级作用域之中声明函数。
    ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。

    // 情况一
    if (true) {
      function f() {}
    }
    
    // 情况二
    try {
      function f() {}
    } catch(e) {
      // ...
    }

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

    所以下面的代码会报错

    // 浏览器的 ES6 环境
    function f() { console.log('I am outside!'); }
    
    (function () {
      if (false) {
        // 重复声明一次函数f
        function f() { console.log('I am inside!'); }
      }
    
      f(); // Uncaught TypeError: f is not a function
    }());
    
    // 相当于:
    
    // 浏览器的 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

    但是在 ES5 环境里, 是可以正常运行, 打印 I am inside!
    所以在块级作用域里用, 建议用函数表达式来声明 let f = function(){}

    3. const 命令

    const声明一个只读的常量。一旦声明,常量的值就不能改变。
    const a = 1;
    a = 2; // Uncaught TypeError: Assignment to constant variable.

    const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,
    const a; // Missing initializer in const declaration

    const的作用域:
    只在声明所在的块级作用域内有效。
    声明的常量也是不提升。
    不可重复声明。

    本质

    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
    对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的

    const foo = {};
    foo.prop = 123; // 成功
    foo = {}; // Uncaught TypeError: Assignment to constant variable.

    ES6 声明变量的六种方法
    var, function, let, const, import, class

    4.顶层对象的属性

    在浏览器环境指的是window对象
    node 环境里没有 window 对象, 有global对象;
    ES6 规定var和function命令声明的全局变量,依旧是顶层对象的属性;
    let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性

    // node 环境里
    var a = 1;
    console.log( global.a ); // 输出1

    // ES6 环境里
    var a = 1;
    window.a // 1

    let b = 1;
    window.b // undefined

    5. global 对象

    浏览器 顶层对象 window 和 self; (window === self // true)
    Web Worker self指向顶层对象
    node global

    全局环境中,this会返回顶层对象。但是,Node模块和ES6模块中,this返回的是当前模块。

  • 相关阅读:
    javascript的基本语法
    javascript的初步认识
    就诊管理(数据结构小学期)
    软件工程课程总结
    每日学习(个人作业2)
    每日学习(个人作业2)
    每日学习(个人作业2)
    每日学习(个人作业2)
    Java中后端Bigdecimal传值到前端精度丢失问题
    这学期的加分项
  • 原文地址:https://www.cnblogs.com/zhengming2016/p/6860575.html
Copyright © 2011-2022 走看看