ES6學習筆記(1)參考書《ECMAScript 6入門》http://es6.ruanyifeng.com/let和const命令let 總結1.聲明變數基本使用方法與var 相同 不同點 a.在代碼塊中使用let聲明的變數只在代碼塊中有效,代碼塊外無法訪問,而用var聲明的在代碼塊外也可以訪問。 ...
參考書《ECMAScript 6入門》
http://es6.ruanyifeng.com/
let和const命令
let 總結
1.聲明變數基本使用方法與var 相同
不同點
a.在代碼塊中使用let聲明的變數只在代碼塊中有效,代碼塊外無法訪問,而用var聲明的在代碼塊外也可以訪問。可以利用這點聲明局部變數,也可用它解決js中的for迴圈閉包的問題
****閉包的解釋****
function out(){//外部函數
var arr = [];
for(var i = 0; i < 3; i ++){
arr[i] = function(){//匿名函數
console.log(i);
}
}
return arr;
}
out()[0]();
期待結果 0
實際結果 2
造成結果偏差的原因就是閉包
閉包的定義:有權訪問另一個函數作用域中的變數的函數
在此例子中,函數out內部創建了另外一個匿名函數,並且這個匿名函數可以訪問out的變數i,這就形成了閉包(實現了匿名函數有權訪問out的作用域中的變數)
解決閉包的方法
M1.匿名函數自執行傳參
function out(){//外部函數
var arr = [];
for(var i = 0; i < 3; i ++){
arr[i] = (function(number){//匿名函數
console.log(number);
})(i);
//使用()()利用匿名函數自執行的方式將參數傳遞給匿名函數使用
//這裡每迴圈執行一次i,i就會作為參數進行匿名函數自執行,然後最終結果就是0,1,2
}
return arr;
}
out();//0,1,2
M2.將參數傳給匿名函數的變數
function out(){//外部函數
var arr = [];
for(var i = 0; i < 3; i ++){
arr[i] = function(number){//匿名函數
console.log(number);
}(i)//和(function(){})()是一個意思,都是告訴瀏覽器自動運行這個匿名函數,這時將參數傳給匿名函數的參數,可以不用加()
}
return arr;
}
out();//0,1,2
M3.let 定義塊級作用域變數的方式
function out(){//外部函數
var arr = [];
for(let i = 0; i < 3; i ++){
arr[i] = function(){//匿名函數
console.log(i);
}
}//let聲明的變數是塊級作用域變數,每次迴圈都生成一個新的變數i,所以console.log(i) 也只能返回for迴圈內部的每次i,無法像var 定義的一樣返回訪問全局的i
return arr;
}
out()[0]();//0
b. let 不支持變數提升
console.log(a); //會報ReferenceError錯誤,表示不存在這個變數。在代碼塊中,使用let/const聲明變數前,變數都是不可用的,稱為“暫時性死區”
a = 23;//ReferenceError
typeof a;//ReferenceError
let c = c;//ReferenceError c還沒有完成變數聲明,不可以用來賦值
function test(x = y,y = 2){return x+y};//ReferenceError: y is not defined 在給x賦值y時,y還沒有聲明
//暫時性死區本質:在塊級作用域里,變數只有等到聲明變數的那一行代碼出現時,才可以賦值和使用,不然都會報錯
let a = 9;
console.log(b);//undefined 當用var聲明變數時,瀏覽器運行時會先聲明這個變數b,但是b沒有賦值,就輸出undfined
var b = 9;
c.let不支持重覆聲明變數
funtion test(){var a = 1;var a = 2;}
test();//不報錯 undefined
funtion test(){let a = 1;var a = 2;}
test();//報錯 Uncaught SyntaxError: Identifier 'c' has already been declared
funtion test(){var a = 1;let a = 2;}
test();//報錯 Uncaught SyntaxError: Identifier 'c' has already been declared
funtion test(){let a = 1;let a = 2;}
test();//報錯 Uncaught SyntaxError: Identifier 'c' has already been declared
function action(event){let event = event || window.event}
action();//Uncaught SyntaxError: Identifier 'event' has already been declared
function action(event){var event = event || window.event}
action();//不報錯
2. let命令聲明瞭js的塊級作用域
var a = 1;
function test(){
console.log(a);//undefined 此處發生了變數提升,這裡的a指的是if中的那個a
if(true){
var a = 3;
}
console.log(a);//3 此處的a是if中重新聲明賦值的a
}
let b = 1;
function test(){
console.log(b);//1 第一個let作用域內的b
if(true){
let b = 3;
}
console.log(b);//1 第一個let作用域內的b
}
立即執行函數等同於let塊級作用域
(function(){var c = ..........;}())------------{ let c = ......;}
es6可以在塊級代碼中聲明函數
if(true){
function test(){}//函數聲明語句
}
if(true){
let c = function(){}//函數表達式
}
const 總結
1.聲明常量,聲明的同時就要賦值,且不允許再被改變
const NATURE = 3//ok
const NATURE1;//報錯Uncaught SyntaxError: Missing initializer in const declaration,必須聲明的同時賦值
2.塊級作用域,不支持變數提升,暫時性死區,同一作用域內不允許重覆聲明變數與let一致
const obj = {}
obj.name = '123'//ok 給對象增加屬性屬於對象obj的功能
obj = {"name" : "123"};//報錯 常量obj不可以重新賦值
小結:ES6是ES5的升級版
ES5有兩種聲明變數的方法:var,function
ES6有六種聲明變數的方法:var,function,let,const,import,class