zoukankan      html  css  js  c++  java
  • ES6学习笔记之变量声明let,const

    最近用淘宝的weex做了个项目,最近稍微闲下来了。正好很久没有接触RN了,所以趁这个机会系统的学习一下ES6的相关知识。

    孔子说:没有对比就没有伤害。所以我们要拿ES6和ES5好好对比的学习。这样才能明白es6是多少的好,积极的拥抱她!

    1.let

    用let声明的变量,只会在let命令所在的代码块内有效。

    let的块状作用域

    我们来看一个简单的例子:

    'use strict';
    {
        let name = 'cloud';
        var age = 21;
    }
    name;//ReferenceError: name is not defined
    age;//21

    我们在let声明变量name的代码块之外去访问这个变量,结果name是没有定义的。如果我们希望在能访问到name应该怎么做呢?

    'use strict';
    {
        let name = 'cloud';
        var age = 21;
        name;//cloud
    }

    没错,我们在let声明变量的代码块中去访问name变量。结果也正如我们期望的那样,name的值被访问到了。对于高级oo语言而言,他们都是基于块状作用域的。

    所以说,let让我们声明的变量也拥有了块状作用域这样一个概念,而不仅仅是函数作用域了。

    既然有了块级作用域,那把let用来声明循环里的变量是极好的。

    'use strict';
    //死循环
    for(var i = 0; i < 5; i++){
        console.log(i);
        for(var i = 0; i < 3; i++){
            console.log(i);
        }
    }
    
    for(let i = 0; i < 5; i++){
        console.log(i);
        for(let i = 0; i < 3; i++){
            console.log(i);
        }
    }

    如果没有let的话,上面代码中的内循环每次都会把var声明的变量i重置为0,所以毫无疑问,这是一个死循环。所以我们必须把内循环中变量i换成变量j,或者其他的名称。但是这也会带来一个副作用,就是循环完成以后的i,被泄露成了全局变量。

    'use strict';
    for(var i = 0; i < 5; i++){
        i;//0,1,2,3,4
    }
    i;//5
    for(let i = 0; i < 5; i++){
        i;//0,1,2,3,4
    }
    i;//ReferenceError: i is not defined

    let声明的变量不存在变量声明提升

    'use strict';
    name; //undefined
    age; //ReferenceError: age is not defined
    var name = 'cloud';
    let age = 21;

    用var声明的变量name,虽然我们在name使用后才声明并给其赋值,但是因为变量声明提升的原因,我们看到name已经声明了,只是其值是undefined而已。但是用let声明的age变量,却没有定义。所以说let是不存在变量声明提升的。

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

    只要是块级作用域中存在let命令,它所在的区域就成为了暂时性死区,使用let命令声明变量之前,该变量都是不可用的。同时该变量不再受到外部的影响。

    var name = 'new cloud';
    {
    //TDZ start name = 'cloud'; name;//ReferenceError: name is not defined let name;    //TDZ end name;//undefined let name = 'cloud'; name;//cloud }

    如上代码,在let声明name之前,那么这个变量都是不可用的。所以这也带来一个问题,当我们使用typeof这样的反射机制来检测我们的所需的变量是否按照我们设想的那样,typeof不再是一个坚定不移的忠臣了,它也会报错了。

    {
        typeof name;//undefined
        var name = 'cloud';
        typeof name;//ReferenceError: name is not defined
        let name = 'cloud';
    }

    let块状作用域内声明的变量,不允许重复声明。

    1.
    '
    use strict'; var name = 'cloud'; var name = 'new cloud'; name;//new cloud
    2.
    '
    use strict'; { let name = 'cloud'; var name = 'new cloud'; name; let name = 'cloud'; var name = 'new cloud'; name; let name = 'cloud'; let name = 'new cloud'; name; //SyntaxError: Identifier 'name' has already been declared }

    第二段代码中的所有声明方式,都会报错。name已经被声明。

    'use strict';
    function setName(name){
        let name = name;//SyntaxError: Identifier 'name' has already been declared
        {
            let name = 'new cloud';
            console.log(name);//new cloud
        }
        console.log(name);//cloud
    }
    setName('cloud');

    同样,在函数中重新声明变量也会报错的。

    2.const

    const是一个只读的常量。一旦声明,就不可更改。

    'use strict';
    const PI = 3.14;
    PI = 3.1415;//TypeError: Assignment to constant variable

    如果用const声明了常量,但是并没有去初始化它。那么,也是会报错的。

    'use strict';
    const PI;//SyntaxError: Missing initializer in const declaration

    同样,const的作用域与let命令相同:只在声明所在的块级作用域内有效。const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。const声明的常量,也与let一样不可重复声明。

    如果我们用const来声明一个引用类型的话。const只能保证指针域不变,但是并不能保证数据域是不可变更的。

    'use strict';
    const employee = {};
    employee['name'] = 'cloud';
    employee['age'] = 21;
    
    employee = {}; //TypeError: "employee " is read-only
    employee['name'] = 'new cloud';
    console.log(employee.name);//new cloud

    如果想把一个对象完成的冻结的话,应该是用Object.freeze()方法。

    const employee = Object.freeze({});
    employee.name= 'cloud';//TypeError: Can't add property prop, object is not extensible
  • 相关阅读:
    新装的idea需要设置的项目
    bug活动文章地址
    环形链表的问题
    IntelliJ配置jenkins服务的Crumb Data
    算法问题求数组排序后最大相邻数差
    jdk11安装以及无jre解决方法
    算法问题大数相加
    java中级技术点
    算法实现 出入栈,寻找最小值
    算法问题2的整数次幂
  • 原文地址:https://www.cnblogs.com/ChengWuyi/p/6062095.html
Copyright © 2011-2022 走看看