Es6从入门到放弃①

近来闲来无事,一直在看阮一峰的ES6入门。
在此做下笔记,记录所学内容。

Let命令

一直觉得let这个和var 长得最像了,不过两者还是有很大的差别。

特性-1.变量只在当前作用域下有效(生成一个块级作用域)

例如

1
2
3
4
5
6
7
8
9
10
11
var 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
4
console.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
5
var 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
5
var a="zone";
if(true){
let a;
a="赵日天";
}

这样就能正常运行了。不过 在全局作用域中,a的值还是zone,原因我在第一点就已经说过了。

let不允许在相同的作用域内,连续声明两次同一个变量。

例如

1
2
3
4
function () {
let a = "赵日天";
let a = "zone";
}

恩,这样会报错的。就算你是赵日天也不能连续声明两次。。。不过我想一般学到ES6的,也不会傻到在同一个作用域中连续声明两次同一个变量。。。。


ES6中新增的块级作用域

对于当初学JS的时候,我就很好奇,为什么JS不存在块级作用域,而只有全局作用域和函数作用域。这样有时候会照成一些不合理的情况。
例如:

1
2
3
4
5
6
7
8
9
var 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
18
function 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命令

前面提到 Letvar,这里介绍下第三种声明变量的方式.const
和前面两个不同是:const是个只读的常量,用一句话来说就是:当这个常量一旦声明,常量的值就不能改变了。是不是觉得很坑爹。。。。
例如

1
2
const a="zone";
a="赵日天"//这里会报错

另外因为const一旦声明之后,取值不能改变,所以,一般对于const来说,只声明不赋值就会报错,因为他只有一次赋值的机会,就是声明的那一次

constlet的相同点

  • 作用域相同,都存在块级作用域,声明的变量只在块级作用域中有效。
  • 都不支持变量提升,也同样存在暂时性死区。
  • 当然还有 都不能重复声明,这一点已经很明显了。
  • 在全局变量中申明的时候,两者皆不算在全局变量中
    例如:
    0_1468396336369_upload-ea091323-01ae-4347-839f-1b793828a246

对于复合型变量

对于复合型变量,变量名不指向数据,而是指向数据所在的地址(相当于对于简单变量,赋值的一个具体数字,而对于引用类型的变量,赋值的是一个指针,指向储存这个变量的地址)这点和ES5的简单类型和引用类型相似。
例如

1
2
3
4
const a={};
a.name="zone";
console.log(a.name);
a={"age":18,"other":"yicheng"}