zoukankan      html  css  js  c++  java
  • 【03】const

    【03】const
    魔芋总结:
    1,声明的是常量,一经声明,不得修改。必须声明的同时并赋值。否则报错。
    2,只在声明所在的块级作用域内有效。
    3,const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
    4,也与let一样不可重复声明。
    5,对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。(指针的概念。)
    const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心。
     
    6,ES5只有两种声明变量的方法:var命令和function命令。ES6除了添加let和const命令,另外两种声明变量的方法:import命令和class命令。所以,ES6一共有6种声明变量的方法。
    7,ES6规定,var命令和function命令声明的全局变量,依旧是全局对象的属性;
    let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。
     

    const命令
    const用来声明变量,但是声明的是常量。一旦声明,常量的值就不能改变。
    const PI = 3.1415;
    PI // 3.1415
    
    PI = 3;
    // TypeError: "PI" is read-only
    
     
    上面代码表明改变常量的值会报错。
    const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
    const foo;
    // SyntaxError: missing = in const declaration
    
     
    上面代码表示,对于const来说,只声明不赋值,就会报错。
    const的作用域与let命令相同:只在声明所在的块级作用域内有效。
    if (true) {
      const MAX = 5;}
    
    MAX // Uncaught ReferenceError: MAX is not defined
    
     
    const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
    if (true) {
      console.log(MAX); // ReferenceError
      const MAX = 5;}
    
     
    上面代码在常量MAX声明之前就调用,结果报错。
    const声明的常量,也与let一样不可重复声明。
    var message = "Hello!";let age = 25;
    // 以下两行都会报错
    const message = "Goodbye!";
    const age = 30;
    
     
    对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。
    const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心。
    const foo = {};
    foo.prop = 123;
    
    foo.prop
    // 123
    
    foo = {} // TypeError: "foo" is read-only不起作用
    
     
    上面代码中,常量foo储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。
     
    下面是另一个例子。
    const a = [];
    a.push("Hello"); // 可执行
    a.length = 0;    // 可执行
    a = ["Dave"];    // 报错
    
     
    上面代码中,常量a是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给a,就会报错。
     

     
    如果真的想将对象冻结,应该使用Object.freeze方法。
    const foo = Object.freeze({});
    foo.prop = 123; // 不起作用
    
     
    上面代码中,常量foo指向一个冻结的对象,所以添加新属性不起作用。
     
    除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。
    var constantize = (obj) => {
    	Object.freeze(obj);
    	Object.keys(obj).forEach((key, value) => {
    		if (typeof obj[key] === 'object') {
    			constantize(obj[key]);
    		}
    	});
    };
    
     

     
     
    跨模块常量
    上面说过,const声明的常量只在当前代码块有效。如果想设置跨模块的常量,可以采用下面的写法。
    // constants.js 模块
    export const A = 1;
    export const B = 3;
    export const C = 4;
    // test1.js 模块
    import * as constants from './constants';
    console.log(constants.A); // 1
    console.log(constants.B); // 3
    
    // test2.js 模块
    import {A, B} from './constants';
    console.log(A); // 1
    console.log(B); // 3
    
     
     
     
    全局对象的属性
    全局对象是最顶层的对象,在浏览器环境指的是window象,在Node.js指的是global对象。ES5之中,全局对象的属性与全局变量是等价的。
    window.a = 1;
    a // 1
    
    a = 2;
    window.a // 2
    
     
    上面代码中,全局对象的属性赋值与全局变量的赋值,是同一件事。(对于Node来说,这一条只对REPL环境适用,模块环境之中,全局变量必须显式声明成global对象的属性。)
    这种规定被视为JavaScript语言的一大问题,因为很容易不知不觉就创建了全局变量。
     
    ES6为了改变这一点,一方面规定,var命令和function命令声明的全局变量,依旧是全局对象的属性;
    另一方面规定,let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。
     
    var a = 1;
    // 如果在Node的REPL环境,可以写成global.a
    // 或者采用通用方法,写成this.a
    window.a // 1
    let b = 1;
    window.b // undefined
    
     
    上面代码中,全局变量avar命令声明,所以它是全局对象的属性;全局变量blet命令声明,所以它不是全局对象的属性,返回undefined
     

    原文作者:阮一峰
     
     

    **

  • 相关阅读:
    如何找出一个数组中第二大的数
    如何把一个整型数组中重复的数字去掉
    假设数组a有n个元素,元素取值范围是1~n,如何判定数组是否存在重复元素
    如何重新排列数组使得数组左边为奇数,右边为偶数,并使得空间复杂度为O(1),时间复杂度为O(n)
    给一个由n-1个整数组成的未排序的序列,其元素都是1~n中的不同的整数。如何在线性时间复杂度内寻找序列中缺失的整数
    已知大小分别为m、n的两个无序数组A、B和一个常数c,求满足A[i]+B[j]=c的所有A[i]和B[j]
    如何找出数组中符合条件的数对
    如何找出数组中出现奇数次的元素
    云服务器ECS挖矿木马病毒处理和解决方案
    Java下载https文件上传到阿里云oss服务器
  • 原文地址:https://www.cnblogs.com/moyuling/p/8992551.html
Copyright © 2011-2022 走看看