你可以看我之前的博文
这次是更深入的讲解。
声明常量
基本语法
1 2 3 4 5 6 7
| <body> <script> var es = "es6"; es = "es2015"; console.log(es); </script> </body>
|
ES3 语法
自我规定,字母大写是常量,但是,还是可以改变
1 2 3 4 5 6 7
| <body> <script> var ES = "es6"; ES = "es2015"; console.log(ES); </script> </body>
|
ES5
预先设置
1 2 3 4 5 6 7 8 9 10 11
| <body> <script> Object.defineProperties(window, 'es', { value: "es6", writable: false, }) es = "2015" console.log(es) </script> </body>
|
上述代码执行出现
Uncaught TypeError: Property description must be an object: e
at Function.defineProperties (<anonymous>)
ES6
1 2 3 4 5 6 7
| <body> <script> const es = "es6"; es = "2015" console.log(es) </script> </body>
|
出现
Uncaught TypeError: Assignment to constant variable
const
开始就要赋值
1 2 3 4 5
| <script> const es; es = "2015" console.log(es) </script>
|
上面的语法是错误的,要一开始就要初始化值。
const && var
变量重名
1 2 3
| var es = "6"; var es = "2015" console.log(es)
|
这是被允许的
1 2
| const es = "6"; const es = "2015";
|
这是不被允许的
所属权
1 2 3
| var es = "6"; console.log(es); console.log(window.es);
|
上面两个输出是一样的,通过 var
声明的变量,属于顶层 window
。
1 2 3
| const es = "6"; console.log(es); console.log(window.es);
|
第二个输出为 undefined
。 const
不属于顶层。
变量提升
1 2
| console.log(es); var es = "6";
|
输出的是 undefined
,这个叫做变量提升,相当于
1 2 3
| var es; console.log(es); es = "6";
|
但是对于 const
来说
1 2
| console.log(es); const es = "6";
|
是错误的,const
的不能进行变量提升。所以,const
声明的更加安全。
作用域
1 2 3 4
| if(true){ var es = "6"; } console.log(es);
|
和你预想的输出一样,因为 var
声明的属于 window
。
1 2 3 4
| if(true){ const es = "6"; } console.log(es);
|
这个会报错,const
声明有作用域。
深入理解 const
1 2 3 4 5
| const es = { name:"es6", }; es.name = "2015"; console.log(es.name);
|
输出 2015
。
对于引用数据类型是可以修改内部内容的。「下面这幅图可以说明一切」
引用数据类型不可变
1 2 3 4 5 6
| const es = { name:"es6", }; Object.freeze(es); es.name = "2015"; console.log(es.name);
|
输出是 es6
。
深层次数据类型不可变
1 2 3 4 5 6 7 8 9
| const es = { name:"es6", values:["6","7","8"] }; Object.freeze(es); es.values = ["9"]; console.log(es.values); es.values[0] = "10"; console.log(es.values);
|
- 第一个输出 [“6”,”7”,”8”]
- 第二个输出 [“10”,”7”,”8”]
道理也很简单,在这里不解释了。
如果想要深层次数据不可变,就需要递归冻结。
1 2 3 4 5 6 7 8 9 10 11 12 13
| const es = { name:"es6", values:["6","7","8"] };
function myFreeze(obj){ Object.freeze(obj); Object.keys(obj).forEach(function (key){ if(typeof obj[key] === "object"){ Object.freeze(obj[key]) } }) }
|