一.let
let命令的基本用法和 var 差不多,几乎一样,就是用来声明变量的,为什么有了var 还要有一个let呢?我找到了几个答案
1.es6之前,js和普通的程序开发语言有很大不同,它的一些特点(缺点)让它够不上一项程序语言的标准。其中在变量声明这一点有些不合理。es6推荐使用let声明变量就是想要让js逐渐走上一条标准的开发语言之路。
2.var 不废除,也是为了兼容,估计有一天var就会看不见了 。总之,let让js开发更标准,更易理解,更减少错误,等。
1.let不存在变量提升
变量提升: 变量在声明之前就可以使用(undefined), 表现类似于变量在所有执行代码之前就已经声明过。 (var 是变量提升的)
a = 123
var a ;
console.log(a) //123
a = 123
let a;
console.log(a) //error
优点: 开发中不必担心随手声明了变量,有可能导致变量覆盖,污染,而且使得开发更加严谨,出错率少。
2.let变量的暂时性死区
暂时性死区: 代码块内,变量声明之前,变量不可用,前提是这个代码块内必须存在这个变量的声明,如果不存在,访问外部作用域。
let a = 456
if(true){
a = 123 //error
let a;
}
这个特性使得typeof方法不一定安全,也是为了让开发者习惯于在变量声明之后再使用变量。
3.let变量不允许重复声明
确切的说是不允许在同一作用域中重复声明
二.块级作用域
es6之前只有全局和函数作用域,不存在块级作用域,所以出现了一些很奇怪的现象
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
if代码块里面的内容在不存在块级作用域的情况下,相当于直接在函数中,也就是说,函数中存在tmp变量声明(变量提升),所以输出undefined,可是这个结果和想要的不一样。
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
循环使用的变量变成了全局变量,因为不存在块级作用域,所以直接是全局作用域。
1.es6块级作用域
es6新增了块级作用域,这个块级作用域基于let命令,在代码块中,使用let命令声明变量,则在这个代码块中形成自己的作用域(只用let命令声明的变量有效,var 无效)
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
2.函数声明在块级作用域中
es5不允许在代码块中声明函数,但是es6允许,es6在代码快中声明的函数相当于使用let一样的性质,存在块级作用域。
块级作用域总结: es6的块级作用域是存在的,这一切的基础在于-变量需要let声明,函数则没有限制
三.const
const 用来声明常量,它和let用相同的特性,只是它声明的
变量指向的值不可修改而已(不存在变量提升,暂时性死区都存在),所以常量也需要先声明再使用啊。
注意: const 变量指向的值不可改变,仔细想想,在声明基本类型(字符串,数字,bool),它的变量确实是不可改变的,因为变量指向‘值’, 但是在声明引用类型(对象)的时候,指向的值就是引用的指针而已,指针不可以改变,但是其中的值可以改变啊。
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
在用const 声明引用类型变量的时候,一定要注意。
这里使用的的例子,参照阮一峰的
es6入门