使用let危尿,不會造成變量提升
ES5
console.log(test); //結(jié)果是undefined
var test = 'test';
可以理解為:
var test;
console.log(test); //結(jié)果是undefined
test = 'test';
ES6
console.log(test); //結(jié)果是ReferenceError:test is not defined
let test = 'test';
因為不存在變量提升呐萌,可以理解為:
console.log(test);
let test; //上不去哩,所以報錯了谊娇。
test = 'test';
作用在塊級作用域
首先要科普一下塊級作用域:
在ES6之前javascript是用函數(shù)function來劃分作用域肺孤,于是定義的變量作用在各個函數(shù)里,單獨或者嵌套济欢,也造成了函數(shù)作用域鏈赠堵。
現(xiàn)在ES6定義了塊級作用域,用{}(if法褥、for等使用了{}才具備塊級作用域的條件)劃分塊級作用域茫叭,let在塊級作用域定義的變量在離開塊級作用域的時候會被銷毀,所以在塊級作用域內(nèi)定義的變量在塊級作用域外訪問的話會報引用錯誤(ReferenceError)
ES5
{
var a = 1;
}
console.log(a); //結(jié)果為1
ES6
{
let a = 1;
}
console.log(a) //結(jié)果是ReferenceError: a is not defined
不允許重復(fù)聲明變量
ES5
{
var a = 1;
var a = 2; //我照樣過得好好的~
}
ES6
{
let a = 1;
let a = 2; //出錯啦~,SyntaxError: Identifier 'a' has already been declared
}
暫時性死區(qū)(temporal dead zone半等,簡稱 TDZ)
ES6明確規(guī)定揍愁,如果區(qū)塊中存在let和const命令,這個區(qū)塊對這些命令聲明的變量杀饵,從一開始就形成了封閉作用域莽囤。凡是在聲明之前就使用這些變量,就會報錯切距。
沒有l(wèi)et的區(qū)塊(無論是es5還是es6)
{
tmp = 'abc';
console.log(tmp); //結(jié)果為abc
}
{
tmp = 'abc';
console.log(tmp); //結(jié)果為abc
var tmp; //這里定義的tmp將會變量提升烁登,相當于移動這個語句在tmp = 'abc'上面。
}
有l(wèi)et的區(qū)塊
{
// TDZ開始蔚舀,因為下面出現(xiàn)了let tmp饵沧,所以let以上的語句出現(xiàn)暫時性死區(qū)
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結(jié)束,let tmp以下的語句沒有暫時性死區(qū)赌躺,因為這里let tmp沒有賦值狼牺,所以下面報undefined的錯
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
typeof
typeof也會報錯
{
typeof test; //ReferenceError: test is not defined
let test = 2;
}
隱蔽的暫時性死區(qū)
function bar(x = y,y = 2){
return [x,y]
}
bar(); //ReferenceError: y is not defined
在塊級作用域里聲明函數(shù)
ES5嚴格模式下(非嚴格模式下不會報錯)
'use strict';
if (true){
function test(){console.log('test')}
}
test(); //ReferenceError:test is not defined
ES6允許在塊級作用域聲明函數(shù)
非嚴格模式
if (true) {
function test() {console.log('test')}
}
test(); //結(jié)果為test
嚴格模式
不用var、let礼患、const定義:
'use strict';
if (true) {
function test() {console.log('test')} //由于function沒有加var是钥、let、const定義缅叠,所以此函數(shù)的作用域是全局的
}
test() //結(jié)果為test
var:
'use strict';
if (true){
var test = function(){console.log('test')} //由于function是用var定義的悄泥,所以此函數(shù)是當前function作用域,此處為global
}
test() //結(jié)果為test
let或者const:
'use strict';
if (true){
let test = function(){console.log('test')} //由于function是用let定義的肤粱,所以此函數(shù)是當前塊級作用域弹囚,即是{}包括的區(qū)域,離開之后變量被銷毀
}
test() //結(jié)果為ReferenceError: test is not defined
const定義常量
不可以重新賦值
const test = 1;
test = 0; //TypeError: Assignment to constant variable.
一旦定義就必須初始化
const test; //SyntaxError: Missing initializer in const declaration
const定義的地址不能改變领曼,但是內(nèi)容可以改變
const test = [];
test.push('test');
console.log(test); //['test']