ES6學習總結
JavaScript
是一個持續演進的編程語言,並由瀏覽器廠商、開發者和社區成員組成的委員會制定標準。委員會引入了JavaScript
歷史上的最大更新 ES6
(ES2016),而 ES7
是年度更新的第一版(ES2017)。
2、ES6
和ES7
優點
-
-
簡化常見編程模式
-
使代碼更容易編寫以及定制底層的
JavaScript
行為。
-
3、新特性
-
-
類
Class
可以讓開發者更容易地編寫面向對象程序,並安全地擴展extend
JavaScript內建對象。 -
箭頭函數
Arrow functions
、默認參數default parameters
array convenience methods
使得常用功能更容易編寫,而不需要在項目之間復制黏貼代碼。 -
JavaScript
的異步處理流和嵌套回調讓人難以理解,所以 ES6 中引入了promises
、叠代器和生成器iterators, and generators
以簡化異步代碼,讓控制流更直觀而不易出錯。
-
4、ES6
基礎---let
命令
-
- 用於聲明(局部)變量,類似於var(全局),但是聲明的變量只在let命令所在的代碼塊有效。
-
-
創建塊級作用域(下面詳細介紹)
1 if(true){ 2 let a=10; 3 var
-
沒有變量提升
1 console.log(typeof str); //undefined 2 var str = 10; 3 4 console.log(typeof abc); //Uncaught ReferenceError: abc is not defined 5 let abc = 10;
-
不允許重復聲明
1
-
暫時性死區
在塊級作用域中使用
let
聲明變量時,塊級作用域會形成一個封閉的環境,不能訪問外部聲明的變量1 var c = 19; 2 if(true) { 3 console.log(c); 4 let c; //Uncaught ReferenceError: c is not defined 5 }
-
5、為什麽需要塊級作用域?
ES5 只有全局作用域和函數作用域,沒有塊級作用域,這帶來很多不合理的場景。
-
- 第一種場景----內層變量可能會覆蓋外層變量。
1 var tmp = ‘hi‘; 2 function f() { 3 console.log(tmp); //這裏想使用外層的tmp=‘hi‘ 4 if (false) { //if代碼塊之內使用內層的tmp=‘hello‘ 5 var tmp = ‘hello‘; 6 } 7 } 8 f(); //但是輸出結果是undefined,因為這裏存在變量提升,導致內部tmp覆蓋了外層的tmp
- 第一種場景----內層變量可能會覆蓋外層變量。
-
- 第二種場景----用來計數的循環變量泄露為全局變量。
1 var s = ‘hello‘; 2 for (let i = 0; i < s.length; i++) { 3 console.log(s[i]); 4 } 5 console.log(i); // 5 6 //上面代碼中,變量i只用來控制循環,但是循環結束後,它並沒有消失,泄露成了全局變量
- 第二種場景----用來計數的循環變量泄露為全局變量。
6、ES6
基礎---const
命令
const
聲明一個只讀的常量。
-
-
一旦聲明,常量的值就不能改變
1 const PI = 3.1415; // 3.1415 2 PI = 3; // TypeError: Assignment to constant variable.
-
只聲明,不賦值,也會報錯
1 const a; // SyntaxError: Missing initializer in const declaration
-
-
-
與
1 if (true) { 2 const a = 5; 3 } 4 console.log(a); // Uncaught ReferenceError: a is not defined
-
-
-
1 var message = "Hello!"; 2 let age = 25; 3 4 // 以下兩行都會報錯 5 const message = "Goodbye!"; 6 const age = 30;
- 也沒有變量提升,存在暫時性死區
1 if (true) { 2 console.log(a); //Uncaught ReferenceError: a is not defined 3 const a = 5; 4 }
-
7、ES6
聲明變量的六種方法
-
ES5
只有兩種聲明變量的方法:var
命令和function
命令。ES6
除了添加let
和const
命令,另外兩種聲明變量的方法:import
命令和class
命令。所以,ES6
一共有6種聲明變量的方法。
8、箭頭函數
-
- ES6 允許使用“箭頭”(
=>
)定義函數。1 var f = v => v;
- ES6 允許使用“箭頭”(
-
- 上面箭頭函數等同於
1 var f = function(v) { return v;};
- 上面箭頭函數等同於
-
- 引入箭頭函數的兩個作用
- 更簡短的函數書寫,簡化回調函數
1 // 正常函數寫法 2 [1,2,3].map(function (x) { 3 return x * x; 4 }); 5 // 箭頭函數寫法 6 [1,2,3].map(x => x * x);
- 更簡短的函數書寫,簡化回調函數
- 引入箭頭函數的兩個作用
-
- 使用時需註意
- 函數體內的
this
對象,就是定義時所在的對象,而不是使用時所在的對象。 - 不可以當作構造函數,也就是說,不可以使用
new
命令,否則會拋出一個錯誤。 - 不可以使用
arguments
對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替。 - 不可以使用
yield
命令,因此箭頭函數不能用作 Generator 函數1 //this對象的指向是可變的,但是在箭頭函數中,它是固定的。 2 function foo() { 3 setTimeout(() => { 4 console.log(‘id:‘, this.id); 5 }, 100); 6 } 7 var id = 21; 8 foo.call({ id: 42 }); // id: 42 9 //箭頭函數可以讓setTimeout裏面的this,綁定定義時所在的作用域,而不是指向運行時所在的作用域
- 函數體內的
- 使用時需註意
-
- 小測試:請問下面的代碼中有幾個this?
1 function foo() { 2 return () => { 3 return () => { 4 return () => { 5 console.log(‘id:‘, this.id); 6 }; 7 }; 8 }; 9 } 10 11 var f = foo.call({id: 1}); 12 13 var t1 = f.call({id: 2})()(); // id: 1 14 var t2 = f().call({id: 3})(); // id: 1 15 var t3 = f()().call({id: 4}); // id: 1
- 小測試:請問下面的代碼中有幾個this?
上面代碼之中,只有一個this
,就是函數foo
的this
,所以t1
、t2
、t3
都輸出同樣的結果。因為所有的內層函數都是箭頭函數,都沒有自己的this
,它們的this
其實都是最外層foo
函數的this
。
除了this
,以下三個變量在箭頭函數之中也是不存在的,指向外層函數的對應變量:arguments
、super
、new.target
。
9、promise對象
-
- 異步編程的一種解決方案
- 避免了層層嵌套的回調函數,使用鏈式調用方式來組織代碼,更加直觀
- 提供統一的接口,使得控制異步操作更加容易。
- 三種狀態
- Pending進行中
- Resolved已完成(又稱Fulfilled)
- Rejected已失敗
- 基本用法
1 //創造一個promise實例 2 var promise = new Promise(function(resolve, reject) { 3 // ... some code 4 5 if (/* 異步操作成功 */){ 6 resolve(value); 7 } else { 8 reject(error); 9 } 10 }); 11 //實例生成後,可以用then方法分別指定Resolved狀態和Reject狀態的回調函數。 12 promise.then(function(value) { 13 // success 14 }, function(error) { 15 // failure 16 });
- promise.all()
- 異步編程的一種解決方案
-
-
-
var p = Promise.all([p1, p2, p3]);
-
p
的狀態由p1
、p2
、p3
決定,分成兩種情況。(1)只有
p1
、p2
、p3
的狀態都變成fulfilled
,p
的狀態才會變成fulfilled
,此時p1
、p2
、p3
的返回值組成一個數組,傳遞給p
的回調函數。(2)只要
p1
、p2
、p3
之中有一個被1 // 生成一個Promise對象的數組 2 var promises = [2, 3, 5, 7, 11, 13].map(function (id) { 3 return getJSON(‘/post/‘ + id + ".json"); 4 }); 5 ? 6 Promise.all(promises).then(function (posts) { 7 // ... 8 }).catch(function(reason){ 9 // ... 10 }); //上面代碼中,promises是包含6個 Promise 實例的數組,只有這6個實例的狀態都變成fulfilled,或者其中有一個變為rejected,才會調用Promise.all方法後面的回調函數
-
-
先到這裏吧!有什麽不對的地方望大家多多指點!
ES6學習總結