zoukankan      html  css  js  c++  java
  • 《理解 ES6》阅读整理:块绑定(Block Binding)

    变量声明一直是JavaScript中一个需要技巧的部分。在大多数基于C的编程语言中,变量(更正式地说是绑定)在声明的时候创建,然而在JavaScript中并不是这样。在JavaScript中,变量在何处创建取决于你用什么方式声明它。ES6提供了新的声明方式,让你可以更容易控制变量的作用域。接下来将说明为什么用var声明变量容易造成困扰以及ES6的块级绑定。

    var声明和提升(var Declarations and Hoisting)

    在JavaScript中,用var做变量声明相当于在函数顶部声明变量(如果在函数外面声明,那么变量拥有全局作用域),而不管这个变量实际上在何处声明,这称为提升(hoisting)。下面的例子可以说明什么是提升:

    复制代码
    function getValue(condition) {
        if (condition) {
            var value = "blue";
            return value;
        } else {
            //在这里value是可以被访问,值为undefined
            return null;
        }
        //在这里value是可以被访问,值为undefined
    }
    复制代码

    如果你不了解JavaScript,你可能认为变量value只有在condition为true的时候才被创建。但实际上变量value无论如何也会被创建。上面这段代码实际上与下面这段代码效果一样:

    复制代码
    function getValue(condition) {
        var value;
        if (condition) {
            value = "blue";
            return value;
        } else {
            return null;
        }
    }
    复制代码

    可以看到,value的声明被提升到函数顶部,但是仍然在初始的位置完成初始化操作。这意味着变量value在else分支也可以被访问到,但在else中访问value其值为undefined因为在else块中并没有初始化value。变量提升通常给JavaScript新手带来困惑,并且在实际项目带来bug。因为这个原因,ES6提供了块级作用域选项让开发者更好的控制变量的生命周期。

    块级声明(Block-Level Declarations)

    块级声明的含义是:在变量声明的块作用域外,不能访问此变量。块级声明以下面两种方式声明:

      (1)在函数内声明

      (2)在块内声明(以{}包含)

    很多基于C的语言都支持块级声明,ES6提供块级声明也是想让开发者拥有同样的开发灵活性。

    let声明(let Declarations)

    let的声明语言和var的声明语言是一样的。你可以将代码中的var用let替换,从而将变量的作用范围限制在当前块内。用let声明的变量不会被提升到块的顶部。最好是在块的最开始部分用let声明变量,这样在整个块内就都能访问到变量。来看下面的示例代码:

    复制代码
    function getValue(condition) {
        if (condition) {
            let value = "blue";
            return value;
        } else {
            //在这里value不能被访问
            return null;
        }
        //在这里value不能被访问
    }
    复制代码

    上面的getValue函数实际上很像我们在其他基于C的语言中声明的函数。value变量是用let声明的,不会被提升,所以现在只能在if块内访问到value变量。如果condition为false,那么value变量永远也不会被声明或初始化。

    禁止重复声明(No Redeclaration)

     如果某个变量已经在作用域内声明,那么用let再次声明这个变量,就会报错。请看下面的代码:

    var count = 30;
    
    let count = 40;  //报错

    在上面的代码中,count被声明两次:var和let各声明一次。因为let不能重复定义一个已经存在的变量,所以上面的代码会抛出错误。但是如果let是在自己块内声明一个同名变量,将不会报错:

    var count = 30;
    
    if (condition) {
        let count = 40;  //没有报错
    }

     这里let定义count变量不会报错,是因为它在if块内创建的,而不是在外部的块。在if块内访问count的值为40,而不是外面的30。这与C/C++等语言的作用方式是一样的。

    常量声明(const Declarations)

    ES6支持用关键字const作常量声明。用const声明的变量在初始化后不能被修改。每个const变量在声明时必须被初始化,看下面的代码:

    const maxItems = 30;
    
    const name;  //语法错误,name没被初始化

     maxItens在声明时被初始化,而name在声明时未被初始化,因而会报错。

    常量声明 vs let声明(Constants vs. let Declarations)

    const声明和let声明一样,都是块级声明,也就是说在块内用const声明的变量无法在块外被访问。const声明的变量也不会被提升。看下面的代码:

    if (condition) {
        const maxItems = 5;
    }
    //这里不能访问到maxItems变量

     const另外一个与let相似的性质是,在作用域内也不能重复声明变量。不管这个变量是用var还是let声明的。看下面的代码:

    var message = "Hello";
    let age = 25;
    
    //下面两句都会报错
    const message = "Goodbye!";
    const age = 30;

    在这些相似的性质之外,const和let之间还有一个重要的不同之处。对一个已经用const声明的变量赋值会报错,不管是strict还是non-strict模式:

    const maxItems = 5;
    
    maxItems = 5;  //报错

    const声明对象(Object Declarations with const)

    const声明的对象可以修改对象的属性,看下面的代码:

    复制代码
    const person = {
        name: "Nicholas"
    };
    
    person.name = "Greg";  //没问题
    
    //报错
    person = {
        name: "Greg"
    };
    复制代码

    简单的说就是用const声明的变量,本身绑定的值不能变,但是指向的对象却是可以修改的。

  • 相关阅读:
    第六章 函数与宏定义实验
    第五章 循环结构实验
    第五章 循环结构课内反思
    第四章 分支结构实验
    C程序设计实验报告
    509寝室小组
    第九章 构造数据类型实验
    第八次实验报告
    数组实验
    函数与宏定义实验
  • 原文地址:https://www.cnblogs.com/libin-1/p/5950965.html
Copyright © 2011-2022 走看看