ES6:也就使es2015,這一版更新了很是重要的知識點,也是目前前端面試內容佔比最多的一部分前端
一、let,const.es6
1.11塊級做用域:見到這種變量首先想到的就是es6新添了一種做用域,塊級做用域。而生效過程即便在有let和const存在就會有會計做用域,顧名思義就是在大括號裏有做用域,即for,if等語句中也存在做用域面試
1.12不存在變量提高:傳統的會有變量提高,先var v1;console.log(v1);v1=2;let不存在變量提高就會報錯shell
1.13統一塊級做用域不容許重複聲明 redux
1.13const聲明時必須賦值 ,不然報錯,且const a=引用類型數據時改變不會報錯數組
1.14暫時性死區:一個塊級做用域內部若是定義了局部變量,就不會使用外部變量。promise
二、結構賦值,其實很簡單,就是一一對應對象或數組中的值進行賦值(介紹的比較簡單,其實很複雜,字符串也能夠結構賦值等等...結構賦值的知識點比較多,也很雜,有興趣的能夠單獨瞭解一下,這裏介紹最經常使用的)數據結構
let [a, [[b], c]] = [1, [[2], 3]];
console.log(a, b, c); // 1, 2, 3
let [ , , c] = [1, 2, 3];
console.log(c); // 3
let [a, , c] = [1, 2, 3];
console.log(a,c); // 1, 3
let [a, ...b] = [1, 2, 3];
console.log(a,b); // 1, [2,3]
let [a, b, ..c.] = [1];
console.log(a, b, c); // 1, undefined, []
三、字符串函數的拓展,在String.prototype上添加了一些方法 異步
includes():返回布爾值,表示是否找到參數字符串。
startsWith():返回布爾值,表示參數字符串是否在原字符串的頭部。
endsWith():返回布爾值,表示參數字符串是否在原字符串的尾部。
repeat方法返回一個新字符串,表示將原字符串重複n次。
第一個 參數是查詢的值,第二個參數是開始查詢的下標,容許負數,及倒數。。async
includes和indexOf十分類似,但注意的是includes支持識別NaN等
四、模板字符串、用了這個就能減小字符串的拼接了,最討厭的就是字符串拼接,如今這種十分牛X的功能解決一項心腹大患
// ES6以前
let a = 'abc' + v1 + 'def';
// ES6以後
let a = `abc${v1}def`
五、箭頭函數,箭頭函數沒有做用域,this指向外部做用域,箭頭函數是函數的簡化
var fn=x=>x;fn(5)
function fn(x){//不用箭頭函數
return x
}
六、Array.from方法用於將相似數組的對象或可遍歷的對象轉爲真正的數組
七、參數默認值
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
log('Hello', undefined) // Hello World
八、
ES6 引入 rest 參數(形式爲「...變量名」),用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。rest 參數搭配的變量是一個數組,該變量將多餘的參數放入數組中。
rest 參數中的變量表明一個數組,因此數組特有的方法均可以用於這個變量。下面是一個利用 rest 參數改寫數組push方法的例子。
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
console.log(item);
});
}
var a = [];
push(a, 1, 2, 3)
//注意,rest 參數以後不能再有其餘參數(即只能是最後一個參數),不然會報錯。
九、Symbol類型,表示獨一無二的值。它是 JS 的第七種數據類型,前六種是:undefined、null、Boolean、String、Number、Object。
var s = Symbol();
typeof(s);
//產生的緣由:爲了防止重名形成的衝突,因此引入了Symbol。
十、ES6 提供了新的數據結構 Set。它相似於數組,可是成員的值都是惟一的,沒有重複的值。
const s = new Set();
// 將數組中的每一個元素,經過add方法,添加到set結構中
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
console.log(Array.from(s));
console.log(s.size); // 獲取長度
console.log(s.has(3)); // 是否存在元素3
console.log(s.delete(2));// 刪除元素2,若是刪除成功,則返回真
console.log(Array.from(s));
//s.clear(); // 清除全部元素,無返回值
//console.log(Array.from(s));
//遍歷:
let set = new Set(["ab", "xx", "123"]);
set.forEach((value, key, arr) => console.log(value, key, arr) ) // 注意:value和key相同
//forEach支持第二個參數,用來綁定this,但箭頭函數中,this永遠指向window
const obj = {
fn: function(key, value) {
console.log(key, value);
}
};
let set = new Set(["ab", "xx", "123"]);
set.forEach(function(value, key, arr){
this.fn(key, value);
}, obj)
十一、map結構:
JavaScript 的對象(Object),本質上是鍵值對的集合(Hash 結構),可是傳統上只能用
字符串看成鍵。這給它的使用帶來了很大的限制。
const data = {};
const element = document.getElementById('myDiv');
data[element] = 'metadata';
data['[object HTMLDivElement]'] // "metadata"
上面代碼原意是將一個 DOM 節點做爲對象data的鍵,可是因爲對象只接受字符串做爲鍵名,
因此element被自動轉爲字符串[object HTMLDivElement]。
爲了解決這個問題,ES6 提供了 Map 數據結構。它相似於對象,也是鍵值對的集合,
可是「鍵」的範圍不限於字符串,各類類型的值(包括對象)均可以看成鍵。也就是說,
Object 結構提供了「字符串—值」的對應,Map結構提供了「值—值」的對應,是一種更
完善的 Hash 結構實現。若是你須要「鍵值對」的數據結構,Map 比 Object 更合適。
const m = new Map();
const o = {p: 'Hello World'};
console.log(o); // {p: 'Hello World'}
m.set(o, 'content')
console.log(m.get(o)); // "content"
console.log(m.has(o)); // true
console.log(m.delete(o)); // true
console.log(m.has(o)); // false
上面代碼使用 Map 結構的set方法,將對象o看成m的一個鍵,而後又使用get方法讀取這個鍵。
十二、generators生成器函數,如今已經逐漸被async函數取代,可是redux-saga仍是基於它實現的
注意:
1. 與普通函數相比,生成器函數須要在 關鍵字function 和 函數名之間,加一個星號,星號先後是否寫空格無所謂,帶有星號的函數,就是生成器函數,即 Generator函數。
2. yield相似return,中文爲產出的意思,表示程序執行到 yield時,程序暫停,產出一個結果,這個結果爲對象 {value: 值, done:[false| true]},value指的就是yield後面跟的值,done指程序是否已經完成。
3. 生成器函數自己只返回一個對象,這個對象具備next方法,執行next方法時,函數體內容碰到yield纔會暫停
Generator 函數,它最大的特色,就是能夠交出函數的執行權,即暫停執行。
function * fn(num1, num2){
var a = num1 + num2;
yield a;
var b = a - num2;
yield b;
var c = b * num2;
yield c;
var d = c / num2;
yield d;
}
var f = fn(1, 2);
console.log( f.next() ); // {value:3, done:false}
console.log( f.next() ); // {value:1, done:false}
console.log( f.next() ); // {value:2, done:false}
console.log( f.next() ); // {value:1, done:false}
console.log( f.next() ); // {value:undefined, done:true}
es7:es7的內容就不多了,嚴格來講就兩點
一、Array.prototype.includes()方法
includes()用於查找一個值是否在數組中,若是在返回true,不然返回false。
['a', 'b', 'c'].includes('a'); // true
['a', 'b', 'c'].includes('d'); // false
2.2 指數操做符(**)
let a = 3 ** 2 ; // 9
// 等效於
Math.pow(3, 2); // 9
es8:es8主要更新了一個受人吹捧的async函數,很是好用,但仍是基於promise的,因此promise仍是很重要的!!!
ES8引入async函數,是爲了使異步操做更加方便,其實它就是Generator函數的語法糖。
async函數使用起來,只要把Generator函數的**(*)**號換成async,yield換成await便可。對好比下:
// Generator寫法
const fs = require('fs');
const readFile = function (fileName) {
return new Promise(function (resolve, reject) {
fs.readFile(fileName, function(error, data) {
if (error) return reject(error);
resolve(data);
});
});
};
const gen = function* () {
const f1 = yield readFile('/etc/fstab');
const f2 = yield readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
// async await寫法
const asyncReadFile = async function () {
const f1 = await readFile('/etc/fstab');
const f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
對比Genenrator有四個優勢:
(1)內置執行器 Generator函數執行須要有執行器,而async函數自帶執行器,即async函數與普通函數如出一轍:
async f();
(2)更好的語義 async和await,比起星號和yield,語義更清楚了。async表示函數裏有異步操做,await表示緊跟在後面的表達式須要等待結果。
(3)更廣的適用性 yield命令後面只能是 Thunk 函數或 Promise 對象,而async函數的await命令後面,能夠是 Promise 對象和原始類型的值(數值、字符串和布爾值,但這時等同於同步操做)。
(4)返回值是Promise async函數的返回值是 Promise 對象,這比 Generator 函數的返回值是 Iterator 對象方便多了。你能夠用then方法指定下一步的操做。
進一步說,async函數徹底能夠看做多個異步操做,包裝成的一個 Promise 對象,而await命令就是內部then命令的語法糖。
async函數返回一個Promise對象,可使用then方法添加回調函數,函數執行時,遇到await就會先返回,等到異步操做完成,在繼續執行。
async function f(item){
let a = await g(item);
let b = await h(item);
return b;
}
f('hello').then(res => {
console.log(res);
})
async代表該函數內部有異步操做,調用該函數時,會當即返回一個Promise對象。
另外還有個定時的案例,指定時間後執行:
function f (ms){
return new Promise(res => {
setTimeout(res, ms);
});
}
async function g(val, ms){
await f(ms);
console.log(val);
}
g('leo', 50);
async函數還有不少使用形式:
// 函數聲明
async function f (){...}
// 函數表達式
let f = async function (){...}
// 對象的方法
let a = {
async f(){...}
}
a.f().then(...)
// Class的方法
class c {
constructor(){...}
async f(){...}
}
// 箭頭函數
let f = async () => {...}
返回Promise對象
async內部return返回的值會做爲then方法的參數,另外只有async函數內部的異步操做執行完,纔會執行then方法指定的回調函數。
async function f(){
return 'leo';
}
f().then(res => { console.log (res) }); // 'leo'
async內部拋出的錯誤,會被catch接收。
async function f(){
throw new Error('err');
}
f().then (
v => console.log(v),
e => console.log(e)
)
// Error: err
await命令
一般await後面是一個Promise對象,若是不是就返回對應的值。
async function f(){
return await 10;
}
f().then(v => console.log(v)); // 10
咱們經常將async await和try..catch一塊兒使用,而且能夠放多個await命令,也是防止異步操做失敗由於中斷後續異步操做的狀況。
async function f(){
try{
await Promise.reject('err');
}catch(err){ ... }
return await Promise.resolve('leo');
}
f().then(v => console.log(v)); // 'leo'
使用注意
(1)await命令放在try...catch代碼塊中,防止Promise返回rejected。
(2)若多個await後面的異步操做不存在繼發關係,最好讓他們同時執行。
// 效率低
let a = await f();
let b = await g();
// 效率高
let [a, b] = await Promise.all([f(), g()]);
// 或者
let a = f();
let b = g();
let a1 = await a();
let b1 = await b();
(3)await命令只能用在async函數之中,若是用在普通函數,就會報錯。
// 錯誤
async function f(){
let a = [{}, {}, {}];
a.forEach(v =>{ // 報錯,forEach是普通函數
await post(v);
});
}
// 正確
async function f(){
let a = [{}, {}, {}];
for(let k of a){
await post(k);
}
}
二、Object原型上加了一些方法,Object.values(),Object.entries()
咱們知道Object.keys(),是把對象的key放到一個數組中,那麼values是把value放到數組中,entries是把key,value都放到數組中
var a = { f1: 'hi', f2: 'leo'};
Object.keys(a); // ['f1', 'f2']
let a = { f1: 'hi', f2: 'leo'};//若是不是對象返回空數組
Object.values(a); // ['hi', 'leo']
let a = { f1: 'hi', f2: 'leo'};
Object.entries(a); // [['f1','hi'], ['f2', 'leo']]
三、字符串填充 padStart和padEnd
用來爲字符串填充特定字符串,而且都有兩個參數:字符串目標長度和填充字段,第二個參數可選,默認空格。
'es8'.padStart(2); // 'es8''es8'.padStart(5); // ' es8''es8'.padStart(6, 'woof'); // 'wooes8''es8'.padStart(14, 'wow'); // 'wowwowwowwoes8''es8'.padStart(7, '0'); // '0000es8' 'es8'.padEnd(2); // 'es8''es8'.padEnd(5); // 'es8 ''es8'.padEnd(6, 'woof'); // 'es8woo''es8'.padEnd(14, 'wow'); // 'es8wowwowwowwo''es8'.padEnd(7, '6'); // 'es86666'從上面結果來看,填充函數只有在字符長度小於目標長度時纔有效,若字符長度已經等於或小於目標長度時,填充字符不會起做用,並且目標長度若是小於字符串自己長度時,字符串也不會作截斷處理,只會原樣輸出。————————————————版權聲明:本文爲CSDN博主「zuggs_」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/zuggs_/article/details/84825227