var 与let,const的区别:
- let所声明的变量只在let命令所在的代码块内有效
- let不存在“变量提升”现象,变量必须在声明后使用
- 只要块级作用域内存在let和const命令,则这个区块对这些命令声明的变量从一开始就形成封闭作用域
- 不允许重复声明
- let实际上为js新增了块级作用域
1、let用来声明变量,其所声明的变量只在let命令所在的代码块内有效
下面的代码如果使用var,最后输出的是10。
$(function(){ var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10 })
如果使用let,声明的变量仅在块级作用域内有效,最后输出的是6。
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
for (let i = 0; i < 3; i++) { let i = 'abc'; console.log(i); } // abc // abc // abc
2、不存在变量提升
var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
// var 的情况 console.log(foo); // 输出undefined var foo = 2; // let 的情况 console.log(bar); // 报错ReferenceError let bar = 2;
3、暂时性死区
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }
在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
4、不允许重复声明
let不允许在相同作用域内,重复声明同一个变量。
// 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; } function func(arg) { let arg; // 报错 } function func(arg) { { let arg; // 不报错 } }
const命令
const声明一个只读的常量。一旦声明,常量的值就不能改变。
所有的 const 声明的变量都必须在声明处初始化。
// 合法的声明 const maxItems = 30; // 语法错误:未初始化 const name;
const 和 let 都是块级声明,意味着执行流跳出声明所在的代码块后就没有办法在访问它们,同样 const 变量也不会被提升,示例如下:
if (condition) { const maxItems = 5; // 其它代码 } // maxItems 在这里无法访问
另一处和 let 相同的地方是,const 也不能对已存在的标识符重复定义,不论该标识符由 var(全局或函数级作用域)还是 let (块级作用域)定义。例如以下的代码:
var message = "Hello!"; let age = 25; // 下面每条语句都会抛出错误 const message = "Goodbye!"; const age = 30;
const 和 let 的差异:const 变量都不允许被重复赋值。
const maxItems = 5; maxItems = 6; // 抛出错误
将对象赋值给 const 变量
const 声明只是阻止变量和值的再次绑定而不是值本身的修改。这意味着 const 不能限制对于值的类型为对象的变量的修改,示例如下:
const person = { name: "Nicholas" }; // 正常 person.name = "Greg"; // 抛出错误 person = { name: "Greg" };
【注】const 阻止的是绑定的修改,而不是绑定值的修改。
关于es6的学习资料:
1、http://es6.ruanyifeng.com/#docs/let
2、https://oshotokill.gitbooks.io/understandinges6-simplified-chinese/content/chapter_1.html