近来闲来无事,一直在看阮一峰的ES6入门。
在此做下笔记,记录所学内容。
Let
命令
一直觉得let
这个和var
长得最像了,不过两者还是有很大的差别。
特性-1.变量只在当前作用域下有效(生成一个块级作用域)
例如1
2
3
4
5
6
7
8
9
10
11var a=1;
if(a>0){
var a=2;
let b=1;
}
(function abn (){
var c=3;
})()
console.log(a);
console.log(b);
console.log(c);
我们这里可以发现.当console.log(b)
和console.log(c)
的时候,都报错了。显示a,b is not defiend
对于c 是undefied
的原因我们知道,是因为:
- 这里
(function(){})()
这里创建了一个块级作用域。 - 和
c
类似这里Let
的作用也是创建块级作用域,相当于我这里声明的变量只在我这个”花括号”之内执行.出了这个”花括号”,对不起,我就不认识你了。
特性2.不存在变量提升。
比如下面这个例子1
2
3
4console.log(a);
console.log(b);
var a=1;
let b=2;
这里运行结果显示b is not defined
,这里var a=1
发生了变量提升,相当于 一开始我就已经默认运行了这一条指令var a
已经声明了a,只是还未定义值,这里第一个console.log(a)
会输出undefined
。
额外提一点:暂时性死区。
我们来看这一段代码:1
2
3
4
5var a="zone";
if(true){
a="赵日天";
let a;
}
这里情况是,一开始a
被赋值为zone
,但是在if
语句中偶遇了 let a
;这时候 a
开始被var
结果又会怎么样呢?我运行了一下。
结果结果竟然是a is not undefined
这里我开始的猜测是:let a
基本上很强势,在他的地盘(花括号之内),不管你在其它地方是如何,但是在这里,就必须从新按照我的规则来,这里我定义了 a,但是并不存在变量提升,所以就报错了
我们把代码改一下:1
2
3
4
5var a="zone";
if(true){
let a;
a="赵日天";
}
这样就能正常运行了。不过 在全局作用域中,a
的值还是zone
,原因我在第一点就已经说过了。
let
不允许在相同的作用域内,连续声明两次同一个变量。
例如1
2
3
4function () {
let a = "赵日天";
let a = "zone";
}
恩,这样会报错的。就算你是赵日天也不能连续声明两次。。。不过我想一般学到ES6的,也不会傻到在同一个作用域中连续声明两次同一个变量。。。。
ES6中新增的块级作用域
对于当初学JS的时候,我就很好奇,为什么JS不存在块级作用域,而只有全局作用域和函数作用域。这样有时候会照成一些不合理的情况。
例如:1
2
3
4
5
6
7
8
9var tmp ="赵日天";
function f() {
console.log(tmp);
if (false) {
var tmp = "hello world";
}
}
f();
当函数执行的时候,这里在控制台却输出undefined
这里,主要是原因是发生了变量提升。整体流程应该是:
var tmp
;//这里记过是undefined 未定义console.log(tmp)
这里自然输出undefined
咯。
而let
实际作用相当于为javascript
新增了块级作用域。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function f1() {
let n = 5;
if (true) {
let b = 10;
console.log(n);
console.log(b)
}
console.log(n);
console.log(b);
}
这里就是ES6 let创建作用域的一个很好的例子.
相当于嵌套了两层块级作用域,
执行结果依次输出:
5;
10;
5;
b is not undefined;
原因很简单,这里就不做过多解释了。
这样一来 在ES5所使用的创建块级作用域的方法:利用自运行函数来创建一个块级作用域,有些情况可以用let
来代替了。1
2
3
4
5
6
7
8(function(){
var a="zone";
})();
{
let a="zone";
}
两者的效果是一样的。
const
命令
前面提到 Let
和var
,这里介绍下第三种声明变量的方式.const
和前面两个不同是:const
是个只读的常量,用一句话来说就是:当这个常量一旦声明,常量的值就不能改变了。是不是觉得很坑爹。。。。
例如1
2const a="zone";
a="赵日天";//这里会报错
另外因为const
一旦声明之后,取值不能改变,所以,一般对于const
来说,只声明不赋值就会报错,因为他只有一次赋值的机会,就是声明的那一次
const
与let
的相同点
- 作用域相同,都存在块级作用域,声明的变量只在块级作用域中有效。
- 都不支持变量提升,也同样存在暂时性死区。
- 当然还有 都不能重复声明,这一点已经很明显了。
- 在全局变量中申明的时候,两者皆不算在全局变量中
例如:
对于复合型变量
对于复合型变量,变量名不指向数据,而是指向数据所在的地址(相当于对于简单变量,赋值的一个具体数字,而对于引用类型的变量,赋值的是一个指针,指向储存这个变量的地址)这点和ES5的简单类型和引用类型相似。
例如1
2
3
4const a={};
a.name="zone";
console.log(a.name);
a={"age":18,"other":"yicheng"}