0%

js | 声明变量

  • const
  • let
  • var

你可以看我之前的博文

这次是更深入的讲解。


声明常量


基本语法

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);

第二个输出为 undefinedconst 不属于顶层。

变量提升

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])
}
})
}
请我喝杯咖啡吧~