ES6語法規(guī)范學(xué)習(xí)
let、const、var 三者比較
-
不存在變量提升
let、const 聲明變量之前無法使用
var 則會存在變量提升,沒聲明就可以使用
-
暫時性死區(qū)
- 在塊級作用域內(nèi),使用let聲明的變量不受塊級外的全局變量等的影響。
-
不允許重復(fù)聲明
- let在相同作用域內(nèi)不允許重復(fù)聲明
-
const聲明常量,聲明的常量不允許改變
- 注意一點,const指向的是變量所在地址,對于變量中的數(shù)據(jù)結(jié)構(gòu)則不能控制了
例如,聲明一個數(shù)組,可以向數(shù)組內(nèi)增加數(shù)據(jù),但是無法對數(shù)組內(nèi)的值更改。
變量的賦值
- 相比較以前而言可以進行匹配賦值。
let [a, b, c] = [1, 2, 3];
- 只要某種數(shù)據(jù)結(jié)構(gòu)具有 Iterator 接口,都可以采用數(shù)組形式的解構(gòu)賦值。
賦值案例
function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
let [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
- 解構(gòu)賦值允許指定默認(rèn)值。
let [foo = true] = [];
* 默認(rèn)值還可以變量,前提是這個變量已經(jīng)聲明
- 對象賦值
let { foo: foo1, bar: bar1 } = { foo: 'aaa', bar: 'bbb' };
* 變量名的被賦值的是后者,例如foo:foo1,被賦值的是foo1,而不是foo。foo是匹配等號右邊屬性名為foo的,將其賦值給foo1
- 對嵌套對象進行賦值
const node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
let { loc, loc: { start }, loc: { start: { line }} } = node;
console.log(loc);
console.log(start);
console.log(line);
輸出結(jié)果:
{ start: { line: 1, column: 5 } }
{ line: 1, column: 5 }
1
-
解構(gòu)賦值常用用途
交換值
函數(shù)可以有多個返回值
設(shè)定函數(shù)參數(shù)默認(rèn)值
解析JSON對象中數(shù)據(jù)
…………
函數(shù)
可以設(shè)定默認(rèn)參數(shù)了。
-
使用參數(shù)默認(rèn)值時,函數(shù)不能有同名參數(shù)。
- 函數(shù)同名時 后面的函數(shù)會覆蓋前面的函數(shù)
函數(shù)參數(shù)值可以設(shè)定為undefined 表示此參數(shù)可以省略
-
rest參數(shù)
- 寫法 (rest參數(shù)后不能再有其他參數(shù))
function 函數(shù)名(...變量名)實例
funciton rest(...arr){}- 函數(shù)的length屬性,不包含rest參數(shù)
name屬性 調(diào)用name屬性返回函數(shù)名
ES6中匿名函數(shù)會返回實際函數(shù)名,在ES5中是空串
-
箭頭函數(shù)
ES6中新的函數(shù)定義 可以使用
=>定義函數(shù)函數(shù)體內(nèi)只有返回語句或單條語句,則可以省略
{},注意單條語句若不想要返回值 在=>后加void
例如,
var canntReturn=cannt=>void 1- 函數(shù)只有單個參數(shù)可以省略
()
例如:
var first=first=>1- 函數(shù)的只有一個返回語句,返回值是對象時,要注意加上
()
例如,
var obj=()=>({name:"obj"});-
注意事項
this指向的問題,this指向的是函數(shù)生效時所在的對象
不可使用new命令,不能當(dāng)作構(gòu)造函數(shù)
無法使用arguments對象,不過可用rest替代
不能用作Generator函數(shù)
//第一點的案例 function foo() setTimeout(() => { console.log('id:', this.id); }, 100);} var id = 21; foo.call({ id: 42 }); //對于這里的call函數(shù)作用,原理等在下一個日報將進行分析。 -
不適用場景
對象內(nèi)的方法定義
需要動態(tài)this的時候,像點擊事件操作dom對象時,這里this指的就是這個dom
需要大量讀寫,函數(shù)體復(fù)雜時,使用普通函數(shù)
-
尾調(diào)用優(yōu)化
尾調(diào)用優(yōu)化指不需要保存外層函數(shù)調(diào)用幀,直接用內(nèi)存調(diào)用幀取代外層調(diào)用幀
尾調(diào)用優(yōu)化是為了節(jié)省內(nèi)存
尾遞歸 就非常適合采用尾遞歸優(yōu)化,這樣 不會導(dǎo)致棧溢出
尾調(diào)用優(yōu)化,僅在嚴(yán)格模式下開啟。
在非嚴(yán)格模式下,我們可以將尾調(diào)用遞歸改寫成循環(huán),從而實現(xiàn)尾調(diào)用優(yōu)化。
Set
Set本身是一個構(gòu)造函數(shù),用來生成 Set 數(shù)據(jù)結(jié)構(gòu)。
可利用Set去重復(fù) 利用rest和解構(gòu)賦值
let arr=[1,1,2,2,3];
let arr1=[...new Set(arr)];
Set 插入和遍歷順序一致。
-
Set遍歷方法
Set.prototype.keys():返回鍵名的遍歷器
Set.prototype.values():返回鍵值的遍歷器
Set.prototype.entries():返回鍵值對的遍歷器
Set.prototype.forEach():使用回調(diào)函數(shù)遍歷每個成員
Set實現(xiàn)交并差的實例
let a = new Set([1, 2, 3]); let b = new Set([4, 3, 2]); // 并集 let union = new Set([...a, ...b]); // Set {1, 2, 3, 4} // 交集 let intersect = new Set([...a].filter(x => b.has(x))); // set {2, 3} // 差集 let difference = new Set([...a].filter(x => !b.has(x))); // Set {1}
pomise 對象
用于異步操作
從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。Promise 提供統(tǒng)一的 API,各種異步操作都可以用同樣的方法進行處理。
-
Promise的兩個特點
-
自身狀態(tài)不受外界影響。只有異步操作結(jié)果能改變 這三種狀態(tài)如下:
pending(進行中)
fulfilled(已成功)
rejected(已失?。?/p>
-
2. 狀態(tài)改變后,不會變,任何時候都可以去獲取結(jié)果。例如,事件不監(jiān)聽,但在結(jié)果產(chǎn)生后再設(shè)置監(jiān)聽,無法再獲取結(jié)果,而對于Promise不影響。
- 基本用法及實例解析
var promise = new Promise(function (resolve, reject) {
if (/* 異步操作成功 */) {
resolve(data);
} else {
/* 異步操作失敗 */
reject(error);
}
});
上面參數(shù)作用
resolve函數(shù)的作用:在異步操作成功時調(diào)用,并將異步操作的結(jié)果,作為參數(shù)傳遞出去;
reject函數(shù)的作用:在異步操作失敗時調(diào)用,并將異步操作報出的錯誤,作為參數(shù)傳遞出去。
在Promise生成后,用 then 方法分別指定 resolved 狀態(tài)和 reject 狀態(tài)的回調(diào)函數(shù)
promise.then(function(data) {
// do something when success
}, function(error) {
// do something when failure
});
第二個 function(error) 不是必選項,可以省略
這是reject函數(shù) 回調(diào)的。
一個具體的實例
var promise = new Promise(function(resolve, reject) {
console.log('before resolved');
resolve();
console.log('after resolved');
});
promise.then(function() {
console.log('resolved');
});
console.log('outer');
輸出結(jié)果為
before resolved
after resolved
outer
resolved
解釋:resolve的回調(diào)只有在同步操作全部完成后才能執(zhí)行
異步圖片加載實例
//url 傳入的相對地址 這個方法是返回一個Promise對象實例。
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
//html中的Image對象,在NODEJS環(huán)境下
//Image未定義
const image = new Image();
//onload 當(dāng)圖像裝載完畢時調(diào)用的事件句柄。
image.onload = function() {
//當(dāng)圖片加載成功后調(diào)用resolve
resolve(image);
};
//onerror 在裝載圖像的過程中發(fā)生錯誤時調(diào)用的事件句柄。
image.onerror = function() {
//當(dāng)圖片加載錯誤后調(diào)用reject
reject(new Error('Could not load image at ' + url));
};
//設(shè)置圖像的 URL
image.src = url;
});
}
注意事項:
-
then的使用.
then方法返回的是一個新的Promise實例,不再是原來的最初的Promise實例。因此可以采用鏈?zhǔn)綄懛?,即then方法后面再調(diào)用另一個then方法。
實例
var p=new Promise(function(resolve,reject){ console.log('創(chuàng)建一個Promise實例'); resolve(1); }); var p2=new Promise(function(resolve,reject){ console.log('創(chuàng)建一個Promise實例'); resolve(1); }); //非鏈?zhǔn)絫hen p.then(function(data){ console.log("開始非鏈?zhǔn)浇Y(jié)構(gòu)的then:") return ++data; }); p.then(function(data){ return ++data; }); p.then(function(data){ console.log("data:"+data); }); //鏈?zhǔn)絫hen p2.then(function(data){ console.log("開始鏈?zhǔn)浇Y(jié)構(gòu)的then:") return ++data; }) .then(function(data){ return ++data; }) .then(function(data){ console.log("data:"+data); });輸出結(jié)果: 創(chuàng)建一個Promise實例 創(chuàng)建一個Promise實例 開始非鏈?zhǔn)浇Y(jié)構(gòu)的then: data:1 開始鏈?zhǔn)浇Y(jié)構(gòu)的then: data:3
模板字符串$ 可以在字符串中嵌入變量
- 例如,
let obj='.js';
let str='index$('obj')';
Module 大致了解
import 輸入其他模塊提供的功能
export 規(guī)定模塊的對外接口
裝飾器
相當(dāng)于切面編程中的切點。
不對函數(shù)使用
在ES7中