博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【03】const
阅读量:5346 次
发布时间:2019-06-15

本文共 2737 字,大约阅读时间需要 9 分钟。

【03】const
魔芋总结:
1,声明的是常量,一经声明,不得修改。必须声明的同时并赋值。否则报错。
2,
只在声明所在的块级作用域内有效。
3,
co
nst命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
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.1415PI = 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// 123foo = {} // 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); // 1console.log(constants.B); // 3// test2.js 模块import {A, B} from './constants';console.log(A); // 1console.log(B); // 3
 
 
 
全局对象的属性
全局对象是最顶层的对象,在浏览器环境指的是
window
象,在Node.js指的是
global
对象。ES5之中,全局对象的属性与全局变量是等价的。
window.a = 1;a // 1a = 2;window.a // 2
 
上面代码中,全局对象的属性赋值与全局变量的赋值,是同一件事。(对于Node来说,这一条只对REPL环境适用,模块环境之中,全局变量必须显式声明成
global
对象的属性。)
这种规定被视为JavaScript语言的一大问题,因为很容易不知不觉就创建了全局变量。
 
ES6为了改变这一点,一方面规定,var命令和function命令声明的全局变量,依旧是全局对象的属性;
另一方面规定,let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。
 
var a = 1;// 如果在Node的REPL环境,可以写成global.a// 或者采用通用方法,写成this.awindow.a // 1let b = 1;window.b // undefined
 
上面代码中,全局变量
a
var
命令声明,所以它是全局对象的属性;全局变量
b
let
命令声明,所以它不是全局对象的属性,返回
undefined
 

原文作者:阮一峰
原文地址:
 
 

**

转载于:https://www.cnblogs.com/moyuling/p/8992551.html

你可能感兴趣的文章
POJ 2960 S-Nim 博弈论 sg函数
查看>>
Dijkstra模版
查看>>
一个简单的插件式后台任务管理程序
查看>>
GDB调试多进程程序
查看>>
组合数
查看>>
CMD批处理延时启动的几个方法
查看>>
转:LoadRunner中web_custom_request 和 web_submit_data的差别
查看>>
HTC G7直刷MIUI开启A2SD+亲测教程
查看>>
shiro的rememberMe不生效
查看>>
const 不兼容的类型限定符问题
查看>>
OpenCV的配置
查看>>
spring Cache + Redis 开发数据字典以及自定义标签
查看>>
成功连上数据库顿感世界美好许多
查看>>
编程注意2
查看>>
《C++ Primer Plus》第12章 类和动态内存分配 学习笔记
查看>>
javascript中sort()排序方法总结
查看>>
实现聊天界面的代码
查看>>
自己生成一个NDK的浅析
查看>>
Excel数据导入到数据库
查看>>
jQuery最佳实践
查看>>