zoukankan      html  css  js  c++  java
  • let、const

    let
    • let声明的变量不提升
     if(true){
            //tmp = 'abc';//ReferenceError
            //console.log(tmp);//ReferenceError
    
            let tmp;  //暂时死区(TDZ)结束,在let命令声明变量tmp之前,都属于变量tmp的死区
            console.log(tmp);//undefined
    
            tmp = 123;
            console.log(tmp);//123
        }
    
        //typeof x;  //ReferenceError   "暂时性死区"也意味着typeof不再是一个百分之百安全的操作,
                   //上面代码中,变量x使用let命令声明,所以在声明之前,都属于x的"死区",只要用到该变量就会报错.因此
                   //typeof运行时就会抛出一个ReferenceError
        //let x;
    
    
        typeof  undeclared_variable;  //undefined   在上面代码中,undeclared_variable是一个不存在的变量名,结果返回"undefined",
                                      //所以,在没有let之前,typeof运算符是百分百安全的,永远不会报错.现在这一点不成立了
    
    
        //var x = x;  //不报错
        let x = x;   //ReferenceError  : x is  not defined
                     //使用let变量声明时,只要变量在还没有声明完成前使用,就会报错.在变量x的声明语句还没有执行完成前,就去取x的值,
                     //导致报错"x未定义"
    
    
    
    
        //报错
        function (){
            let a = 10;
            var a = 1;
        }
        //报错
        function (){
            let a = 10;
            let a = 1;
        }//let不允许在相同的作用域内,重复声明同一个变量.
    
    
        function func(arg){
            let arg;  //报错
        }
    
        function func(arg){
            {
                let arg;  //不报错,新的作用域
            }
        }
    
    块级作用域
    var tmp = new Date();
    
        function f(){
            console.log(tmp);  //undefined
            if(false){
                var tmp = 'hello world';//  if代码块的外部使用外层的tmp变量,内部使用内层的tmp变量,但是,函数f执行后,
                                        //输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量
            }
        }
    
        f();
    
        var s = 'hello';
         for(var i = 0 ;i<s.length;i++){
             console.log(s[i]);// h e l l o
         }
        console.log(i);//5  变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量
    
    
        function f1(){
            let n = 5;
            if(true){
                let n = 10;
            }
            console.log(n); //5
        }
        f1();
    
    
    
        {{{{
            let insane = 'hello world';
            {
                let  insane = 'hello world'
            }
        }}}}   //内层作用域可以定义外层作用域的同名变量
    
    块级作用域与函数声明

    ES5规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明

       //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
    
    
    
        {
            let a = 'secret';
            function f(){   //函数声明语句
                return a;
            }
        }
    
    
        {
            let a = 'secret';
            let f = function (){  //函数表达式
                return a;
            };
        }
        //考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数.如果确实需要,
        // 也应该写成函数表达式,而不是函数声明语句
    
    const
     const PI = 3.1415;
       console.log(PI) //3.1415
    
        PI = 3;// TypeError: Assignment to constant variable.
        // 上面代码表明改变常量的值会报错.const声明的变量不得改变值,这意味着,const一旦表明变量,
        // 就必须初始化,不能留到以后赋值
    
    
        const foo;  // SyntaxError: Missing initializer in const declaration
                    //const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值
                    //对于const来说,只声明不赋值,就会报错
    
        if(true){
            const MAX = 5;
        }
        MAX  //Uncaught ReferenceError: MAX is not defined
             //const的作用域与let命令相同,只在声明所在的块级作用域内有效
    
    
        if(true){
            console.log(MAX); //ReferenceError
            const MAX = 5;
        }   //const命令声明的常量也是不提升,同样存在暂存性死区,只能在声明的位置后面使用
    
    
        var message = "hello!";
        let age = 25;
    
        //一下两行都会报错  const 声明的常量,也与let一样不可重复声明
        const message = "goodbye!";
        const age = 30;
    

    本质

    • const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
    const foo = {};
    
    // 为 foo 添加一个属性,可以成功
    foo.prop = 123;
    foo.prop // 123
    
    // 将 foo 指向另一个对象,就会报错
    foo = {}; // TypeError: "foo" is read-only
    
    
    • 上面代码中,常量foo储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。
    const a = [];
    a.push('Hello'); // 可执行
    a.length = 0;    // 可执行
    a = ['Dave'];    // 报错
    //常量a是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给a,就会报错。
    
  • 相关阅读:
    面试题
    网络编程-1
    excel文件导入数据库--jxl包
    excel文件导入数据库
    1113 Integer Set Partition (25 分)集合分割
    1120 Friend Numbers (20 分)set的使用
    1099 Build A Binary Search Tree (30 分)
    1092 To Buy or Not to Buy (字符串删除)
    1127 ZigZagging on a Tree (30 分)树的层次遍历
    1155 Heap Paths (30 分)判断是否是一个堆
  • 原文地址:https://www.cnblogs.com/hixxcom/p/7412355.html
Copyright © 2011-2022 走看看