1. ECMASript 相關(guān)介紹
1.1 什么是 ECMA
-
ECMA(European Computer Manufacturers Association)中文名稱(chēng)為歐洲計(jì)算機(jī)制造商協(xié)會(huì)附井, 這個(gè)組織的目標(biāo)是評(píng)估、開(kāi)發(fā)和認(rèn)可電信和計(jì)算機(jī)標(biāo)準(zhǔn)盟猖。 1994 年后該組織改名為
Ecma
國(guó)際。
1.2 什么是 ECMAScript
- ECMAScript 是由 Ecma 國(guó)際通過(guò) ECMA-262 標(biāo)準(zhǔn)化的腳本程序設(shè)計(jì)語(yǔ)言。
1.3 什么是 ECMA-262
- Ecma 國(guó)際制定了許多標(biāo)準(zhǔn),而 ECMA-262 只是其中的一個(gè), 所有標(biāo)準(zhǔn)列表查看
1.4 ECMA-262 歷史
版 本 | 時(shí) 間 | 事 項(xiàng) |
---|---|---|
第 1 版 |
1997 年 | 制定了語(yǔ)言的基本語(yǔ)法 |
第 2 版 |
1998 年 | 較小改動(dòng) |
第 3 版 |
1999 年 | 引入正則醋拧、異常處理、格式化輸出等淀弹。 IE 開(kāi)始支持 |
第 4 版 |
2007 年 | 過(guò)于激進(jìn)趁仙,未發(fā)布 |
第 5 版 |
2009 年 | 引入嚴(yán)格模式、 JSON垦页,擴(kuò)展對(duì)象、數(shù)組干奢、原型痊焊、字符串、日期方法 |
第 6 版 |
2015 年 | 模塊化忿峻、面向?qū)ο笳Z(yǔ)法薄啥、Promise、箭頭函數(shù)逛尚、 let垄惧、const、數(shù)組解構(gòu)賦值等等 |
第 7 版 |
2016 年 | 冪運(yùn)算符绰寞、數(shù)組擴(kuò)展到逊、Async/await 關(guān)鍵字 |
第 8 版 |
2017 年 | Async/await铣口、字符串?dāng)U展 |
第 9 版 |
2018 年 | 對(duì)象解構(gòu)賦值、正則擴(kuò)展 |
第 10 版 |
2019 年 | 擴(kuò)展對(duì)象觉壶、數(shù)組方法 |
ES.next |
動(dòng)態(tài)指向下一個(gè)版本 |
注:從 ES6 開(kāi)始脑题,每年發(fā)布一個(gè)版本,版本號(hào)比年份最后一位大 1
1.5 誰(shuí)在維護(hù) ECMA-262
-
TC39(Technical Committee 39)
是推進(jìn)ECMAScript
發(fā)展的委員會(huì)铜靶。其會(huì)員都是公司(其中主要是瀏覽器廠商叔遂,有蘋(píng)果、谷歌争剿、微軟已艰、因特爾等)。 TC39 定期召開(kāi)會(huì)議蚕苇,會(huì)議由會(huì)員公司的代表與特邀專(zhuān)家出席哩掺。
1.6 為什么要學(xué)習(xí) ES6
ES6
的版本變動(dòng)內(nèi)容最多,具有里程碑意義;ES6
加入許多新的語(yǔ)法特性捆蜀,編程實(shí)現(xiàn)更簡(jiǎn)單疮丛、高效;ES6
是前端發(fā)展趨勢(shì),就業(yè)必備技能辆它。
1.7 ES6 兼容性
- 可查看兼容性誊薄;
2. ECMASript 6 新特性
2.1 let關(guān)鍵字
let
關(guān)鍵字用來(lái)聲明變量,使用 let
聲明的變量有幾個(gè)特點(diǎn):
不允許重復(fù)聲明變量;
有塊兒級(jí)作用域;
不存在變量提升(預(yù)解析)锰茉,如之前使用
var
關(guān)鍵字聲明變量時(shí)會(huì)將使用var
聲明 提到最前面呢蔫。var num = 10; 變量提升之后 是將 var num; 提到最前面之后在進(jìn)行賦值操作
;不影響作用域鏈。
應(yīng)用場(chǎng)景:以后聲明變量使用 let 就對(duì)了
飒筑。
let a;
let b, c, d;
let e = 100;
let f = 222, g = 'love you', h = [];
// 1. 變量不能重復(fù)聲明
// let star = '李連杰';
// let star = '吳京';
// 2. 使用var聲明的變量是可以重復(fù)的
// var star = '李連杰';
// var star = '吳京';
// 2. 塊級(jí)作用域全局 函數(shù)片吊,eval
{
let boy = 'lyp';
}
console.log(boy); // 這里是訪(fǎng)問(wèn)不到的
// 3. 不存在變量提升
var song = '666';
// 4. 不影響作用域鏈
{
let school = '王者學(xué)院';
function fun() {
console.log(school);
}
}
2.2 const 關(guān)鍵字
const
關(guān)鍵字用來(lái)聲明常量,const
聲明有以下特點(diǎn):
聲明必須賦初始值;
標(biāo)識(shí)符一般為大寫(xiě);
不允許重復(fù)聲明;
值不允許修改;
塊兒級(jí)作用域协屡。
注意: 對(duì)象屬性修改和數(shù)組元素變化不會(huì)觸發(fā) const 錯(cuò)誤俏脊。 應(yīng)用場(chǎng)景:聲明對(duì)象類(lèi)型使用 const,非對(duì)象類(lèi)型聲明選擇 let
肤晓。
// 聲明常量
const SCHOOL = '王者學(xué)院';
// 1. 常量的聲明一定要初始化
const A;
// 2. 常量的值不能修改
SCHOOL = '666';
// 3. const 有塊級(jí)作用域
{
const UZI = '烏茲';
}
console.log(UZI);
// 4. 一般常量標(biāo)識(shí)符需要大寫(xiě)
// 5. 對(duì)于數(shù)組和對(duì)象的元素修改爷贫,不算對(duì)常量的修改,不會(huì)報(bào)錯(cuò)
const TEAM = ['王大', '王二', '王三'];
TEAM.push('王四');
2.3 變量的解構(gòu)賦值
-
ES6
允許按照一定模式补憾,從數(shù)組和對(duì)象中提取值漫萄,對(duì)變量進(jìn)行賦值,這被稱(chēng)為解構(gòu)賦值盈匾。
// ES6允許按照一定的模式從數(shù)組或者對(duì)象中進(jìn)行提取值腾务,對(duì)變量進(jìn)行賦值
// 這就被稱(chēng)為解構(gòu)賦值
// 1. 數(shù)組的解構(gòu)
const F4 = ['宋小寶', '小沈陽(yáng)', '劉能', '趙四'];
let [song, xiao, liu, zhao] = F4;
console.log(song);
console.log(xiao);
console.log(liu);
console.log(zhao);
// 2. 對(duì)象的解構(gòu)
const obj = {
name: '趙本山',
age: '66',
xiaopin: function () {
console.log('我會(huì)演小品');
}
}
let {xiaopin} = obj;
// 解構(gòu)之后直接調(diào)用
xiaopin();
注意:頻繁使用對(duì)象方法、數(shù)組元素削饵,就可以使用解構(gòu)賦值形式岩瘦。
2.4 模板字符串
模板字符串(template string)
是增強(qiáng)版的字符串未巫, 用反引號(hào)(`)標(biāo)識(shí),特點(diǎn):
字符串中可以出現(xiàn)換行符;
可以使用
${xxx}
形式輸出變量担钮。
// ES6中引入新的聲明字符串的方式 `` '' ""
// 1. 聲明
let str = `我是一個(gè)字符串`;
console.log(str, typeof str);
// 2. 使用模板字符串之后可以直接出現(xiàn)換行符
let star = `
<h1>張三</h1>
<h1>李四</h1>
<h1>王五</h1>
<h1>趙六</h1>
`;
console.log(star);
// 3. 模板字符串中的字符串拼接
let lovest = '歡歡'
let starest = `${lovest}是我最喜歡的人`;
console.log(starest);
注意:當(dāng)遇到字符串與變量拼接的情況使用模板字符串橱赠。
2.5 簡(jiǎn)化對(duì)象寫(xiě)法
-
ES6
允許在大括號(hào)里面,直接寫(xiě)入變量和函數(shù)箫津,作為對(duì)象的屬性和方法狭姨。這樣的書(shū)寫(xiě)更加簡(jiǎn)潔。
let name = '王者學(xué)院';
let slogon = '666';
let improve = function () {
console.log('可以提高你的技能');
}
//屬性和方法簡(jiǎn)寫(xiě)
let atguigu = {
name,
slogon,
improve,
change() {
console.log('可以改變你')
}
};
注意:對(duì)象簡(jiǎn)寫(xiě)形式簡(jiǎn)化了代碼苏遥,所以以后用簡(jiǎn)寫(xiě)就對(duì)了饼拍。
2.6 箭頭函數(shù)
-
ES6
中的箭頭函數(shù)()=>
定義函數(shù)。
/*******************************************************************************************/
// ES6中的箭頭函數(shù) ()=> 定義函數(shù)
/**
* 傳統(tǒng)的聲明函數(shù)的方式
*/
let fn = function (a, b) {
return a + b;
};
console.log(fn(12, 32));
/**
* 使用箭頭函數(shù)的方式聲明一個(gè)函數(shù)
*/
let fun = (a, b) => {
return a + b;
};
// 調(diào)用函數(shù)
console.log(fun(1, 3));
/*******************************************************************************************/
/**
* 箭頭函數(shù) 和 傳統(tǒng)函數(shù)聲明的區(qū)別
*
* 1. this是靜態(tài)的田炭。 this始終是指向函數(shù) 聲明時(shí) 所在作用域 的 this 的值 师抄。無(wú)論怎么改變其this都是不會(huì)改變的
*
*/
function getName() {
console.log(this.name); //
}
let getNameTo = () => {
console.log(this.name);//
};
// 設(shè)置 widow 對(duì)象的name屬性
window.name = 'windowyo';
const SCHOOL = {
name: 'ATLYP'
};
// 使用call調(diào)用改變它的this指向
getName.call(SCHOOL); // 調(diào)用傳統(tǒng)方式聲明的函數(shù)并改變其this指向 ATLYP 指向改變了
getNameTo.call(SCHOOL); // 調(diào)用箭頭函數(shù)方式聲明的函數(shù)并改變其this指向 windowyo 指向未改變
/*******************************************************************************************/
/**
* 箭頭函數(shù)不能作為構(gòu)造函數(shù)創(chuàng)建對(duì)象的
* @param name
* @param age
* @constructor
*/
let Person = (name, age) => {
this.name = name;
this.age = age;
};
// let p = new Person('張三', 23); // Person is not a constructor 箭頭函數(shù)聲明的構(gòu)造函數(shù)不能創(chuàng)建對(duì)象
/*******************************************************************************************/
/**
* 箭頭函數(shù)中是不能使用arguments變量
*/
function useArguments(a, b) {
console.log(arguments);
}
useArguments(12, 34);
let notArguments = (a, b) => {
// console.log(arguments);
}
notArguments(23, 56); // arguments is not defined
/*******************************************************************************************/
/**
* 箭頭函數(shù)的簡(jiǎn)寫(xiě)
*
* 1. 省略小括號(hào),當(dāng)形參有且只有一個(gè)的時(shí)候
*
* 2. 可以省略花括號(hào) 教硫, 當(dāng)代碼體中只有一條語(yǔ)句的時(shí)候叨吮,此時(shí)return也必須省略,而且函數(shù)的執(zhí)行結(jié)果就是函數(shù)的返回值
*/
// 1. 省略小括號(hào)
let add = n => {
return n + n;
};
console.log(add(20)); // 40
// 2. 省略花括號(hào)
let pow = n => n * n;
console.log(pow(20)); // 400
/*******************************************************************************************/
箭頭函數(shù)的注意點(diǎn):
如果形參只有一個(gè)瞬矩,則小括號(hào)可以省略;
函數(shù)體如果只有一條語(yǔ)句茶鉴,則花括號(hào)可以省略,函數(shù)的返回值為該條語(yǔ)句的執(zhí)行結(jié)果;
箭頭函數(shù) this 指向聲明時(shí)所在作用域下
this
的值;;箭頭函數(shù)不能作為構(gòu)造函數(shù)實(shí)例化;
不能使用
arguments
景用。箭頭函數(shù)中this是靜態(tài)的涵叮。 this始終是指向函數(shù) 聲明時(shí) 所在作用域 的 this 的值 。無(wú)論怎么改變其this都是不會(huì)改變的
伞插。
箭頭函數(shù)和實(shí)際的應(yīng)用場(chǎng)景
箭頭函數(shù)中this是靜態(tài)的割粮。 this始終是指向函數(shù) 聲明時(shí) 所在作用域 的 this 的值 。無(wú)論怎么改變其this都是不會(huì)改變的
媚污。箭頭函數(shù)適合與this無(wú)關(guān)的回調(diào)舀瓢、定時(shí)器、數(shù)組的方法回調(diào)耗美。
箭頭函數(shù)不適合與this有關(guān)的回調(diào)氢伟,如 事件回調(diào)、對(duì)象的方法幽歼。
// 獲取dom元素
let ad = document.querySelector('.ad');
/**
* 箭頭函數(shù)不適合作為事件回調(diào) ,但是適合定時(shí)器谬盐,數(shù)組方法等
*/
ad.addEventListener('click', function () {
// 事先保存一個(gè) this
let _this = this;
// 在點(diǎn)擊盒子之后2秒改變盒子的顏色
setTimeout(() => {
// 注意這里的this 因?yàn)檫@里是一個(gè)箭頭函數(shù)甸私,箭頭函數(shù)中的this是靜態(tài)的,其是始終指向聲明時(shí)所在作用域的this的值
// _this.style.backgroundColor = 'pink';
this.style.backgroundColor = 'pink';
}, 2000)
});
// 箭頭函數(shù)適合與 this 無(wú)關(guān)的回調(diào)飞傀、定時(shí)器皇型、數(shù)組的方法回調(diào)
// 過(guò)濾數(shù)組中的元素诬烹,找出其中的偶數(shù)
let arr = [1, 2, 3, 9, 90, 78];
/**
*
* 使用傳統(tǒng)function聲明函數(shù)的方式
* */
let newArrFunction = arr.filter(function (item) {
return item % 2 === 0;
});
console.log(newArrFunction);
/**
* 使用箭頭函數(shù)的方式
* @type {number[]}
*/
let newArr = arr.filter(item => item % 2 === 0);
console.log(newArr);
// 箭頭函數(shù)不適合與this有關(guān)的回調(diào),如事件回調(diào)弃鸦、對(duì)象的方法
注意:箭頭函數(shù)不會(huì)更改 this 指向绞吁,用來(lái)指定回調(diào)函數(shù)會(huì)非常合適。
2.7 rest 參數(shù)
-
ES6
引入rest
參數(shù)唬格,用于獲取函數(shù)的實(shí)參家破,用來(lái)代替arguments
。
// ES6引入rest參數(shù)用于獲取函數(shù)的實(shí)參购岗,用來(lái)代替arguments
// ES5中獲取實(shí)參的方式
function es5Arguments(a, b, c) {
console.log(arguments); // 這是一個(gè)對(duì)象 {1, 2, 3}
}
es5Arguments(1, 2, 3);
// ES6 中的rest參數(shù)
/**
* rest參數(shù)必須放在參數(shù)的最后
*/
function es6Rest(a, b, ...args) {
console.log(a);
console.log(b);
console.log(args); // 這是一個(gè)數(shù)組 [56, 89, 784, 12, 456, 456]
}
es6Rest(12, 23, 56, 89, 784, 12, 456, 456);
注意: rest 參數(shù)非常適合不定個(gè)數(shù)參數(shù)函數(shù)的場(chǎng)景汰聋。
ES6中函數(shù)參數(shù)的默認(rèn)值
ES6中為形參賦初始值 , 具有默認(rèn)值的形參的位置一般靠后喊积。
參數(shù)默認(rèn)值可以與解構(gòu)賦值結(jié)合使用烹困。
/**
* ES6中為形參賦初始值 , 具有默認(rèn)值的形參的位置一般靠后
* @param a
* @param b
* @param c
*/
function add(a = 10, b = 20, c = 30) {
return a + b + c;
}
// 2. 參數(shù)默認(rèn)值可以與解構(gòu)賦值結(jié)合使用
function connect({host = '45.56.47.48', username = 'root', password = '123456', port = '3306'}) {
console.log(host);
console.log(username);
console.log(password);
console.log(port);
}
connect({
host: '127.0.0.1',
username: 'root',
password: 'root',
port: '3306'
});
2.8 spread 擴(kuò)展運(yùn)算符
- 擴(kuò)展運(yùn)算符(
spread
)也是三個(gè)點(diǎn)(...)乾吻。它好比 rest 參數(shù)的逆運(yùn)算髓梅,將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列,對(duì)數(shù)組進(jìn)行解包绎签。
// 擴(kuò)展運(yùn)算符將數(shù)組轉(zhuǎn)換為逗號(hào)分隔的參數(shù)序列
const tfBoy = ['易烊千璽', '王源', '張三'];
function shaBi() {
console.log(arguments);
}
shaBi(...tfBoy);
// 展開(kāi)運(yùn)算符 里面有引用數(shù)據(jù)類(lèi)型的話(huà)也是一個(gè)淺拷貝
let oldArr = ['j', 'f', 'r', 'p'];
let newArr = ['j', 'a', 'v', 'a'];
newArr = oldArr.concat(newArr);
console.log(newArr);
let conCatArr = [...oldArr, ...newArr];
console.log(conCatArr);
// 將偽數(shù)組轉(zhuǎn)換為真正的數(shù)組
let divs = document.querySelectorAll('div'); // 這是一個(gè)偽數(shù)組
// 將偽數(shù)組轉(zhuǎn)換為真實(shí)的數(shù)組
console.log(divs);
let newDivs = [...divs];
console.log(newDivs);
2.9 Symbol
Symbol 基本使用
- ES6 引入了一種新的原始數(shù)據(jù)類(lèi)型Symbol枯饿,表示獨(dú)一無(wú)二的值。它是JavaScript 語(yǔ)言的第七種數(shù)據(jù)類(lèi)型辜御,是一種類(lèi)似于字符串的數(shù)據(jù)類(lèi)型鸭你。
JavaScript 的七種數(shù)據(jù)類(lèi)型
u undefined
。s string symbol
擒权。o Object
袱巨。n null number
。b boolean
碳抄。
Symbol 特點(diǎn)
Symbol
的值是唯一的愉老,用來(lái)解決命名沖突的問(wèn)題。Symbol
值不能與其他數(shù)據(jù)進(jìn)行運(yùn)算剖效。Symbol
定義 的 對(duì)象屬 性 不能 使 用for…in
循 環(huán)遍 歷 嫉入,但 是可 以使用Reflect.ownKeys
來(lái)獲取對(duì)象的所有鍵名。
// 向?qū)ο笾刑砑訉傩院头椒?up down
let game = {
name: '張三',
up: function () {
console.log('我是up');
},
down: function () {
console.log('我是down');
}
};
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.up] = function () {
console.log('我可以向上');
};
game[methods.down] = function () {
console.log('我可以向下');
};
console.log(game);
/****************************************************************************************/
// 第二種方式
let obj = {
name: '張三',
up: function () {
console.log('上');
},
[Symbol('say')]: function () {
console.log('說(shuō)話(huà)');
},
[Symbol('sing')]: function () {
console.log('唱歌');
}
}
console.log(obj);
注: 遇到唯一性的場(chǎng)景時(shí)要想到 Symbol璧尸。
Symbol 內(nèi)置值
- 除了定義自己使用的
Symbol
值以外是牢,ES6
還提供了 11 個(gè)內(nèi)置的Symbol
值俱病,指向語(yǔ)言?xún)?nèi)部使用的方法。 可以稱(chēng)這些方法為魔術(shù)方法,因?yàn)樗鼈儠?huì)在特定的場(chǎng)景下自動(dòng)執(zhí)行合呐。
名稱(chēng) | 作用 |
---|---|
Symbol.hasInstance |
當(dāng)其他對(duì)象使用 instanceof 運(yùn)算符唉韭,判斷是否為該對(duì)象的實(shí)例時(shí),會(huì)調(diào)用這個(gè)方法 |
Symbol.isConcatSpreadable |
對(duì)象的 Symbol.isConcatSpreadable 屬性等于的是一個(gè)布爾值,表示該對(duì)象用于Array.prototype.concat() 時(shí)活烙,是否可以展開(kāi)。 |
Symbol.species |
創(chuàng)建衍生對(duì)象時(shí)遣鼓,會(huì)使用該屬性 |
Symbol.match |
當(dāng)執(zhí)行 str.match(myObject) 時(shí)啸盏,如果該屬性存在,會(huì)調(diào)用它骑祟,返回該方法的返回值回懦。 |
Symbol.replace |
當(dāng)該對(duì)象被 str.replace(myObject) 方法調(diào)用時(shí),會(huì)返回該方法的返回值曾我。 |
Symbol.search |
當(dāng)該對(duì)象被str. search (myObject) 方法調(diào)用時(shí)粉怕,會(huì)返回該方法的返回值。 |
Symbol.split |
當(dāng)該對(duì)象被 str. split (myObject) 方法調(diào)用時(shí)抒巢,會(huì)返回該方法的返回值贫贝。 |
Symbol.iterator |
對(duì)象進(jìn)行for...of 循環(huán)時(shí),會(huì)調(diào)用 Symbol.iterator 方法蛉谜,返回該對(duì)象的默認(rèn)遍歷器 |
Symbol.toPrimitive |
該對(duì)象被轉(zhuǎn)為原始類(lèi)型的值時(shí)稚晚,會(huì)調(diào)用這個(gè)方法,返回該對(duì)象對(duì)應(yīng)的原始類(lèi)型值型诚。 |
Symbol. toStringTag |
在該對(duì)象上面調(diào)用toString 方法時(shí)客燕,返回該方法的返回值 |
Symbol. unscopables |
該對(duì)象指定了使用with 關(guān)鍵字時(shí),哪些屬性會(huì)被with 環(huán)境排除狰贯。 |
- 使用
Symbol.isConcatSpreadable
設(shè)置數(shù)組是否可以進(jìn)行拆解也搓。
// Symbol 內(nèi)置了 11 個(gè)屬性
// [Symbol.hasInstance]
class Person {
static [Symbol.hasInstance](param) {
console.log(param);
console.log('我是用來(lái)檢測(cè)類(lèi)型的');
// 根據(jù)return 返回確定 false 或者 true
}
}
let obj = {};
console.log(obj instanceof Person);
// 數(shù)組是否拆解合并
let oldArr = [1, 2, 3, 4];
let newArr = [4, 5, 6, 7];
newArr[Symbol.isConcatSpreadable] = false; // 設(shè)置是否拆解進(jìn)行連接
newArr = oldArr.concat(newArr);
console.log(newArr);
2.10 迭代器
遍歷器(
Iterator
)就是一種機(jī)制。它是一種接口涵紊,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪(fǎng)問(wèn)機(jī)制傍妒。任何數(shù)據(jù)結(jié)構(gòu)只要部署Iterator
接口,就可以完成遍歷操作摸柄。ES6
創(chuàng)造了一種新的遍歷命令for...of
循環(huán)颤练,Iterator
接口主要供for...of
消費(fèi)。原生具備
iterator
接口的數(shù)據(jù)(可用for of
遍歷)驱负。
Array
Arguments
Set
Map
String
TypedArray
NodeList
工作原理
創(chuàng)建一個(gè)指針對(duì)象嗦玖,指向當(dāng)前數(shù)據(jù)結(jié)構(gòu)的起始位置;
第一次調(diào)用對(duì)象的
next
方法,指針自動(dòng)指向數(shù)據(jù)結(jié)構(gòu)的第一個(gè)成員;接下來(lái)不斷調(diào)用
next
方法跃脊,指針一直往后移動(dòng)宇挫,直到指向最后一個(gè)成員;每調(diào)用
next
方法返回一個(gè)包含value
和done
屬性的對(duì)象。
自定義遍歷數(shù)據(jù)
// 聲明一個(gè)對(duì)象
const banji = {
name: '終極一班',
stu: [
'zhansgan',
'lisi',
'wangwu',
'zhaoliu'
],
/**
*
* 重寫(xiě)迭代器遍歷對(duì)象中的數(shù)組
* */
[Symbol.iterator]() {
let index = 0;
// 保存 this
let _this = this;
return {
next: function () {
if (index < _this.stu.length) {
// 這是迭代器中返回的結(jié)果想
let result = {value: _this.stu[index], done: false};
index++;
return result;
} else {
return {value: undefined, done: true};
}
}
}
}
};
/**
* 使用for ... of ... 遍歷
*/
for (let item of banji) {
console.log(item);
}
2.11 生成器
- 生成器函數(shù)是
ES6
提供的一種異步編程解決方案
酪术,語(yǔ)法行為與傳統(tǒng)函數(shù)完全不同器瘪。
// 生成器是一個(gè)函數(shù) 是一個(gè)異步的編程解決方案
// 異步編程使用的是純回調(diào)函數(shù)
// yield 是函數(shù)代碼的分割符
function* gen() {
console.log('hello generator');
console.log('111');
yield '你是小豬豬';
console.log('222');
yield '你的小尾巴';
console.log('333');
yield '我你';
console.log('444');
}
let iterator = gen();
console.log(iterator);
// 調(diào)用生成器函數(shù)
// console.log(iterator.next());
// console.log(iterator.next());
// console.log(iterator.next());
// console.log(iterator.next());
// 可以使用 for...of... 進(jìn)行遍歷
for (let item of gen()) {
console.log(item);
}
代碼說(shuō)明:
*
的位置沒(méi)有限制;生成器函數(shù)返回的結(jié)果是迭代器對(duì)象,調(diào)用迭代器對(duì)象的
next
方法可以得到yield
語(yǔ)句后的值;yield
相當(dāng)于函數(shù)的暫停標(biāo)記娱局,也可以認(rèn)為是函數(shù)的分隔符,每調(diào)用一次next
方法咧七,執(zhí)行一段代碼;next
方法可以傳遞實(shí)參衰齐,作為yield
語(yǔ)句的返回值。
生成器函數(shù)的參數(shù)
/**
* 生成器函數(shù)
* @param arg
*/
function* gen(arg) {
console.log(arg); // 666
let one = yield '1111';
console.log(one); // 第一個(gè)參數(shù)
let two = yield '2222';
console.log(two); // 第二個(gè)參數(shù)
let three = yield '3333';
console.log(three); // 第三個(gè)參數(shù)
}
// next中可以傳遞參數(shù),參數(shù)將作為yield的返回值返回继阻。
let iterator = gen('666');
iterator.next();
iterator.next('第一個(gè)參數(shù)');
iterator.next('第二個(gè)參數(shù)');
iterator.next('第三個(gè)參數(shù)');
案例 :1s 以后在控制臺(tái)輸出 111 耻涛, 2s之后輸出 222 3s之后輸出333
- 傳統(tǒng)的定時(shí)器嵌套調(diào)用的方式 :容易形成回調(diào)地獄
// 下面這是回調(diào)地獄
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
}, 3000);
}, 2000);
}, 1000);
- 使用生成器函數(shù)解決回調(diào)地獄問(wèn)題
/**
* 使用生成器函數(shù)解決回調(diào)地獄問(wèn)題
*/
function one() {
setTimeout(() => {
console.log('444');
// 執(zhí)行完成調(diào)用下一次
iterator.next();
}, 1000);
}
function two() {
setTimeout(() => {
console.log('555');
// 執(zhí)行完成調(diào)用下一次
iterator.next();
}, 2000);
}
function three() {
setTimeout(() => {
console.log('666');
// 執(zhí)行完成調(diào)用下一次
iterator.next();
}, 3000);
}
let iterator = gen();
/**
* 生成器函數(shù)
*/
function* gen() {
yield one();
yield two();
yield three();
}
iterator.next();
案例 :分時(shí)段(先后)請(qǐng)求數(shù)據(jù) ,先請(qǐng)求用戶(hù)數(shù)據(jù)瘟檩,在請(qǐng)求訂單數(shù)據(jù)抹缕,最后請(qǐng)求商品數(shù)據(jù)
function getUsers() {
setTimeout(() => {
let data = '用戶(hù)數(shù)據(jù)';
iterator.next(data); // 通過(guò)next 將參數(shù)傳遞過(guò)去
}, 1000);
}
function getOrders() {
setTimeout(() => {
let data = '訂單數(shù)據(jù)';
iterator.next(data);
}, 1000);
}
function getGoods() {
setTimeout(() => {
let data = '商品數(shù)據(jù)';
iterator.next(data);
}, 1000);
}
/**
* 生成器函數(shù)
*/
function* gen() {
// 接收第二個(gè)next傳遞過(guò)來(lái)的參數(shù)
let user = yield getUsers();
console.log(user);
let order = yield getOrders();
console.log(order);
let good = yield getGoods();
console.log(good);
}
let iterator = gen();
// 第一次調(diào)用
iterator.next();
2.12 Promise
-
Promise
是 ES6 引入的異步編程的新解決方案。語(yǔ)法上Promise
是一個(gè)構(gòu)造函數(shù)墨辛,用來(lái)封裝異步操作并可以獲取其成功或失敗的結(jié)果卓研。
Promise 解決回調(diào)地獄問(wèn)題
/**
* promise解決回調(diào)地獄的問(wèn)題
* @type {Promise<any>}
*/
// 實(shí)例化 Promise的對(duì)象
const p = new Promise(function (resolve, reject) {
setTimeout(function () {
/*// 成功的情況
let data = '數(shù)據(jù)庫(kù)中的用戶(hù)數(shù)據(jù)';
// resolve 調(diào)用它代表成功
resolve(data);*/
/*************************************************************/
/*// 失敗的情況*/
let error = '獲取數(shù)據(jù)庫(kù)數(shù)據(jù)失敗';
reject(error); // reject 代表失敗
}, 5000);
});
// 調(diào)用promise對(duì)象的then方法
p.then(function (value) {
// 成功
console.log(value);
}, function (reason) {
// 失敗
console.error(reason);
});
Promise + Node 實(shí)現(xiàn)簡(jiǎn)單的文件讀取
- 使用傳統(tǒng)的方式 :
//1. 引入fs模塊
const fs = require('fs'); // 需要node環(huán)境的支持
// 2. 調(diào)用方法讀取文件
/**
* 讀取文件內(nèi)容 data中是一個(gè)· buffer
*/
fs.readFile('../resources/666.md', (error, data) => {
// 如果失敗將會(huì)拋出異常
if (error) {
throw error;
}
console.log(data.toString());
});
- 使用Promise的方式 :
//1. 引入fs模塊
const fs = require('fs'); // 需要node環(huán)境的支持
// 3. 使用 promise 修改讀取文件的操作
const p = new Promise(function (resolve, reject) {
fs.readFile('../resources/666.md', (err, data) => {
if (err) {
// reject 是拒絕的意思
reject(err);
}
// resolve 是解決的意思
resolve(data);
})
});
p.then(function (value) {
console.log(value.toString());
}, function (reason) {
console.log(reason);
});
使用Promise發(fā)送一個(gè)Ajax請(qǐng)求
- 如果有一種情況是需要先發(fā)送一個(gè)請(qǐng)求之后再發(fā)送另一個(gè)請(qǐng)求,如果請(qǐng)求多的情況下可能出現(xiàn)回調(diào)地獄的情況睹簇。
const p = new Promise((resolve, reject) => {
// 1. 創(chuàng)建一個(gè)對(duì)象
const xhr = new XMLHttpRequest();
// 2. 初始化
xhr.open('GET', 'url');
// 3. 發(fā)送
xhr.send();
// 4. 綁定事件
xhr.onreadystatechange = function () {
// 判斷
if (xhr.readyState === 4) {
// 判斷狀態(tài)碼 處于 200 - 299 之間
if (xhr.status >= 200 && xhr.status <= 299) {
// 表示成功
// console.log(xhr.response);
// 表示成功
resolve(xhr.response);
} else {
// console.log(xhr.status);
reject(xhr.status);
}
}
};
});
/**
* 使用then處理結(jié)果奏赘,解決回調(diào)地獄的問(wèn)題
*/
p.then((value) => {
console.log(value);
}, (reason) => {
console.log(reason);
})
Promise.prototype.then 調(diào)用then方法then方法的返回結(jié)果是 Promise對(duì)象,對(duì)象狀態(tài)由回調(diào)函數(shù)的執(zhí)行結(jié)果決定太惠。
如果回調(diào)函數(shù)中返回的結(jié)果是非
Promise
類(lèi)型的屬性狀態(tài)為成功磨淌,返回值為對(duì)象成功的值。如果沒(méi)有return返回結(jié)果凿渊,也是一個(gè)非
Promise
對(duì)象 梁只,此時(shí)Promise
類(lèi)型屬性狀態(tài)為成功。如果回調(diào)函數(shù)中返回的結(jié)果是一個(gè)
Promise
類(lèi)型的對(duì)象埃脏。如果拋出錯(cuò)誤也是失敗的
Promise
的錯(cuò)誤搪锣。
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用戶(hù)數(shù)據(jù)');
}, 1000)
});
const result = p.then((value) => {
console.log(value);
// return 123; // fulfilled 是完成的意思
// 如果拋出異常
// throw new Error('發(fā)生了錯(cuò)誤'); // rejected
// 如果回調(diào)函數(shù)中返回的是一個(gè) Promise 對(duì)象
return new Promise((resolve, reject) => {
resolve('解決'); // fulfilled
});
}, reason => {
console.log(reason);
});
console.log(result);
Promise.prototype.catch 方法類(lèi)似一個(gè)語(yǔ)法糖
const p = new Promise(
(resolve, reject) => {
setTimeout(() => {
reject('出錯(cuò)了!');
}, 1000)
}
);
/**
* catch類(lèi)似一個(gè)語(yǔ)法糖
*/
p.catch((reason) => {
console.warn(reason);
});
2.13 Set
-
ES6
提供了新的數(shù)據(jù)結(jié)構(gòu)Set
(集合) 。它類(lèi)似于數(shù)組剂癌,但成員的值都是唯一的淤翔,集合實(shí)現(xiàn)了iterator
接口,所以可以使用『擴(kuò)展運(yùn)算符』和『for…of…
』進(jìn)行遍歷佩谷,集合的屬性和方法:
size
返回集合的元素個(gè)數(shù);add
增加一個(gè)新元素旁壮,返回當(dāng)前集合;delete
刪除元素,返回boolean
值;has
檢測(cè)集合中是否包含某個(gè)元素谐檀,返回boolean
值;clear
清空集合抡谐,返回undefined
。
let s = new Set();
console.log(typeof s);
let s2 = new Set(['張三', '李四', '王五', '趙六']);
console.log(s2.size);// 4
// add
s2.add('田七');
console.log(s2); //
// delete
s2.delete('張三');
// has
console.log(s2.has('田七')); // true
// clear
// s2.clear();
console.log(s2);
// Set集合實(shí)現(xiàn)了 iterator 接口
// 打印集合
for (let item of s2) {
console.log(item); // 李四 王五 趙六 田七
}
Set 集合實(shí)踐:數(shù)組去重 + 求交集桐猬、并集麦撵、差集
交集:兩個(gè)數(shù)組中同時(shí)擁有的元素。
并集:在數(shù)組一中有,在數(shù)組二中也有免胃。
差集:求數(shù)組一和數(shù)組二的差集音五。在數(shù)組一中存在,但是在數(shù)組二中不存在的元素羔沙。
let arr = [1,2,3,4,5,4,3,2,1];
// 1. 數(shù)組去重
let result = [...new Set(arr)]; // 元素唯一的數(shù)組
console.log(result); // [1,2,3,4,5]
// 2. 交集躺涝,在數(shù)組1 和數(shù)組2 中同時(shí)存在的元素
let array = [1,2,6,8,9,5,4];
// 首先將數(shù)組轉(zhuǎn)換為一個(gè)集合再判斷 arr 中的元素是否在 array 中存在
let publicRes = arr.filter(item => new Set(array).has(item));
// 將得到的數(shù)組通過(guò)集合去重
console.log([...new Set(publicRes)]);// 去重 [1,2,4,5]
// 3. 并集 在數(shù)組1中有在數(shù)組2中也有
let union = [...new Set([...array, ...arr])];
console.log(union); // [1,2,6,8,9,5,4,3]
// 4. 差集 arr 中存在的元素在 array 中不存在的
let diff = array.filter(item => !(new Set(arr).has(item)));
console.log(diff); // [6,8,9]
集合與數(shù)組之間的轉(zhuǎn)換
let oldArr = [3,2,1,5,6,89,5];
// 數(shù)組轉(zhuǎn)集合
let oldSet = new Set(oldArr);
console.log(oldSet); // {3, 2, 1, 5, 6, 89,5}
// 集合轉(zhuǎn)數(shù)組
let newArr = [...oldSet];
console.log(newArr); // [3, 2, 1, 5, 6, 89]
2.14 Map
-
ES6 提供了
Map
數(shù)據(jù)結(jié)構(gòu)。它類(lèi)似于對(duì)象扼雏,也是鍵值對(duì)的集合坚嗜。 但是“鍵”的范圍不限于字符串,各種類(lèi)型的值(包括對(duì)象)都可以當(dāng)作鍵
诗充。 Map 也實(shí)現(xiàn)了iterator
接口苍蔬,所以可以使用『擴(kuò)展運(yùn)算符』和『for…of…』進(jìn)行遍歷。 Map 的屬性和方法:
size
返回Map
的元素個(gè)數(shù);set
增加一個(gè)新元素蝴蜓,返回當(dāng)前Map
;get
返回鍵名對(duì)象的鍵值;has
檢測(cè)Map
中是否包含某個(gè)元素碟绑,返回boolean
值;clear
清空集合,返回undefined
;
// 聲明Map
let m = new Map();
// 添加元素
m.set('name', '仙桃');
m.set('change', function () {
console.log('我發(fā)生了改變');
});
// 鍵是一個(gè)對(duì)象
let key = {
school: 'XT'
};
m.set(key, ['張三', '李四', '王五']);
// size
console.log(m.size); // 3
// 刪除
m.delete('name');
console.log(m); //
// 獲取
console.log(m.get(key)); // ['張三','李四','王五']
console.log(m.get('change')); // f() {console.log('我發(fā)生了改變');}
// 清空
m.clear();
console.log(m); // Map(0)
2.15 class 類(lèi)
-
ES6
提供了更接近傳統(tǒng)語(yǔ)言的寫(xiě)法励翼,引入了Class
(類(lèi))這個(gè)概念蜈敢,作為對(duì)象的模板。通過(guò)class
關(guān)鍵字汽抚,可以定義類(lèi)抓狭。基本上造烁, ES6 的class
可以看作只是一個(gè)語(yǔ)法糖否过,它的絕大部分功能, ES5 都可以做到惭蟋,新的 class 寫(xiě)法只是讓對(duì)象原型的寫(xiě)法更加清晰苗桂、更像面向?qū)ο缶幊痰恼Z(yǔ)法而已。
知識(shí)點(diǎn):
class
聲明類(lèi);constructor
定義構(gòu)造函數(shù)初始化;extends
繼承父類(lèi);super
調(diào)用父級(jí)構(gòu)造方法;static
定義靜態(tài)方法和屬性;父類(lèi)方法可以重寫(xiě)告组。
// 手機(jī)類(lèi)
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
// 添加方法 煤伟, 使用原型對(duì)象添加實(shí)現(xiàn)共享
Phone.prototype.call = function () {
console.log('我可以打電話(huà)');
}
// 實(shí)例化對(duì)象
let huawei = new Phone('榮耀', 3999);
huawei.call();
console.log(huawei);
class Ps5 {
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
play() {
console.log('我可以打游戲');
}
}
// 創(chuàng)建對(duì)象實(shí)例
let ps = new Ps5('任天堂',2999);
ps.play();
console.log(ps);
類(lèi)里面的靜態(tài)成員
/**
* 在ES5中*************************************************
*/
function Phone() {
}
Phone.name = '我是靜態(tài)成員'; // 屬于函數(shù)對(duì)象的 不屬于實(shí)例對(duì)象 為靜態(tài)成員
Phone.change = function () {
console.log('我可以改變世界');
}; // 屬于函數(shù)對(duì)象的 不屬于實(shí)例對(duì)象 為靜態(tài)成員
let nokia = new Phone();
console.log(nokia.name); // undefined
Phone.prototype.size = '5.5';
console.log(nokia.size);
/**
* 在ES6中************************************************
*/
class Person {
// 在類(lèi)中聲明一個(gè)靜態(tài)成員
static name = '王五';
age = 23;
}
console.log(Person.name);
console.log(Person.age); // undefined
let p = new Person();
console.log(p.age);
console.log(p.name); // undefined
ES5中實(shí)現(xiàn)繼承
/**
* ES5中實(shí)現(xiàn)類(lèi)的繼承
*/
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
function OnePlus(brand, price, color, size) {
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
// 設(shè)置子級(jí)構(gòu)造函數(shù)的原型
OnePlus.prototype = new Phone();
OnePlus.prototype.constructor = OnePlus;
// 聲明子類(lèi)方法
OnePlus.prototype.photo = function () {
console.log('我可以打電話(huà)');
}
OnePlus.prototype.playGame = function () {
console.log('我可以玩游戲');
}
// 創(chuàng)建onPlus 實(shí)例
let onePlus = new OnePlus('1+', 2999, '紅色', 5.5);
console.log(onePlus);
onePlus.photo();
onePlus.playGame();
// 原型對(duì)象 和 對(duì)象原型
console.log(OnePlus.prototype);
console.log(onePlus);
ES6 中類(lèi)的繼承
- 也可以對(duì)繼承的方法進(jìn)行重寫(xiě),
但是在重寫(xiě)的方法中不能通過(guò)
super關(guān)鍵字調(diào)用父類(lèi)的該方法木缝。
class Phone {
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
call() {
console.log('我可以打電話(huà)');
}
}
class OnePlus extends Phone {
/**
* 構(gòu)造函數(shù)
*/
constructor(brand, price, color, size) {
super(brand, price); // Phone(this,brand,price);
this.color = color;
this.size = size;
}
photo() {
console.log('拍照');
}
playGame() {
console.log('玩游戲');
}
}
let onePLus = new OnePlus('1+', 3999, '綠色', 6.6);
onePLus.photo(); // 拍照
onePLus.playGame(); // 玩游戲
onePLus.call(); // 我可以打電話(huà)
setter 和 getter 方法
// get 和 set
class Phone {
get price() {
console.log('獲取價(jià)格');
return '2999';
}
set price(newValue) {
console.log('價(jià)格被修改了');
}
}
let s = new Phone();
console.log(s.price);
s.price = '3999';
console.log(s.price);
2.16 ES6中數(shù)值的擴(kuò)展
二進(jìn)制和八進(jìn)制
ES6 提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫(xiě)法便锨,分別用前綴 0b 和 0o 表示。
Number.isFinite() 與 Number.isNaN()
Number.isFinite()
用來(lái)檢查一個(gè)數(shù)值是否為有限的我碟;
Number.isNaN()
用來(lái)檢查一個(gè)值是否為NaN
放案。
Number.parseInt() 與 Number.parseFloat()
ES6
將全局方法parseInt 和 parseFloat
,移植到Number
對(duì)象上面矫俺,使用不變吱殉。
Math.trunc
- 用于去除一個(gè)數(shù)的小數(shù)部分掸冤,返回整數(shù)部分。
Math.sign
- 判斷一個(gè)數(shù)到底是 正數(shù) 還是負(fù)數(shù) 還是零友雳。正數(shù)返回 1 稿湿,負(fù)數(shù)返回 -1 零返回 0
代碼演示
// 1. Number.EPSILON 是JavaScript表示的最小精度
console.log((0.1 + 0.2)); // 0.30000000000000004
// 2. 二進(jìn)制和八進(jìn)制
// 二進(jìn)制
let b = 0b0101;
console.log(b); // 5
// 八進(jìn)制
let o = 0o777;
console.log(o); // 511
// 十進(jìn)制
let d = 10106;
console.log(d); // 10106
// 十六進(jìn)制
let x = 0xfff;
console.log(x);// 4095
// 3. Number.isFinite() 檢測(cè)一個(gè)數(shù)值是否是一個(gè)有限數(shù)
console.log(Number.isFinite(10)); // true
console.log(Number.isFinite(100 / 0)); // false
console.log(Number.isFinite(Infinity)); // false
// 4. Number.isNaN() 檢測(cè)一個(gè)數(shù)值是否為NaN
console.log(Number.isNaN(123));// false
console.log(Number.isNaN(Number.parseInt('kk456')));// true
// 5. Number.parseInt Number.parseFloat字符串轉(zhuǎn)整數(shù)或者浮點(diǎn)數(shù)
let str = '123456';
console.log(str); // 黑色字符串
let num = Number.parseFloat(str);
console.log(num);// 藍(lán)色數(shù)字
str = 'kk456';
num = Number.parseInt(str);
console.log(num);
// 6. Number.isInteger 判斷一個(gè)數(shù)是否為整數(shù)
let intNum = 123;
console.log(Number.isInteger(intNum)); // true
// 7. Math.trunc() 將數(shù)字的小數(shù)部分抹掉
let floatNum = 123.365;
console.log(Math.trunc(floatNum)); // 123
// 8. Math.sign 判斷一個(gè)數(shù)到底是 正數(shù) 還是負(fù)數(shù) 還是零
console.log(Math.sign(10)); // 1
console.log(Math.sign(0)); // 0
console.log(Math.sign(-10)); // -1
Number.isInteger
- Number.isInteger() 用來(lái)判斷一個(gè)數(shù)值是否為整數(shù)。
2.17 對(duì)象擴(kuò)展
ES6 新增了一些 Object
對(duì)象的方法
Object.is
比較兩個(gè)值是否嚴(yán)格相等押赊,與『===』行為基本一致(+0 與 NaN); 在其他情況下的比較情況下NaN
和誰(shuí)比較都是false
缎罢。但是在這里NaN
和NaN
比較就是true
。Object.assign
對(duì)象的合并考杉,將源對(duì)象的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象;__proto__
舰始、setPrototypeOf
崇棠、setPrototypeOf
可以直接設(shè)置對(duì)象的原型。
// 1. Object.is 判斷兩個(gè)值是否完全相等
console.log(Object.is(120, 120)); // true
console.log(Object.is(NaN, NaN)); // true
console.log((NaN === NaN));// false
// NaN 不管和誰(shuí)使用 === 做比較都是false
// 2.Object.assign 對(duì)象合并
const configA = {
driver: 'jdbc.mysql.DataManagerDriver',
url: 'localhost',
username: 'root',
password: 'root',
test: 'test'
};
const configB = {
driver: 'jdbc.mysql.DataManagerDriver',
url: '127.0.0.1',
username: 'admin',
password: '12345'
}
console.log(Object.assign(configA, configB));
console.log(configA);// 已經(jīng)合并
console.log(Object.assign(configB, configA));
// 3. 設(shè)置原型對(duì)象 Object.setPrototypeOf = 設(shè)置原型對(duì)象
const school = {
school: '仙桃大數(shù)據(jù)學(xué)院'
};
const area = {
area: '渝北'
};
Object.setPrototypeOf(school, area);
console.log(school);
// 4. 獲取原型 Object.getPrototypeOf = 獲取原型對(duì)象
console.log(Object.getPrototypeOf(school));
2.18 模塊化
- 模塊化是指將一個(gè)大的程序文件丸卷,拆分成許多小的文件枕稀,然后將小文件組合起來(lái)。
模塊化的好處
防止命名沖突谜嫉;
代碼復(fù)用萎坷;
高維護(hù)性。
模塊化規(guī)范產(chǎn)品
ES6 之前的模塊化規(guī)范有:
CommonJS => NodeJS沐兰、 Browserify
哆档;AMD => requireJS
;CMD => seaJS
住闯。
ES6 模塊化語(yǔ)法
模塊功能主要由兩個(gè)命令構(gòu)成: export
和 import
瓜浸。
export
命令用于規(guī)定模塊的對(duì)外接口;import
命令用于輸入其他模塊提供的功能比原。
export的三種暴露方式
(一) export 分別暴露的方式
/**
* 下面的屬于分別暴露
* @type {string}
*/
export let school = '仙桃大數(shù)據(jù)學(xué)院';
export function teach() {
console.log('傳授大數(shù)據(jù)開(kāi)發(fā)經(jīng)驗(yàn)');
}
(二)export統(tǒng)一暴露的方式
/**
* 統(tǒng)一暴露
* @type {string}
*/
let school = '仙桃大數(shù)據(jù)學(xué)校';
function stuData() {
console.log('學(xué)習(xí)大數(shù)據(jù)');
}
/**
* 統(tǒng)一暴露
*/
export {
school,
stuData
}
(三)export 默認(rèn)暴露的方式
export default {
school:'仙桃大數(shù)據(jù)學(xué)院',
change:function () {
console.log('為技術(shù)而改變');
}
}
import 的三種引入方式
(一) 使用解構(gòu)賦值的方式引入
// m1
import {school,teach} from '../js/m1.js';
console.log(school);
teach();
(二) 如果變量中出現(xiàn)了變量名重復(fù)的情況使用as進(jìn)行重命名
// m2
import {school as xt,stuData} from '../js/m2.js';
console.log(xt);
stuData();
(三) 導(dǎo)入默認(rèn)暴露方式有兩種方式
// m3 導(dǎo)入默認(rèn)暴露
import {default as m3} from '../js/m3.js';
console.log(m3);
// 簡(jiǎn)寫(xiě)形式只針對(duì)默認(rèn)暴露
import m3Default from '../js/m3.js';
console.log(m3Default);
m3Default.change();
瀏覽器中使用模塊化的方式
- 將模塊的引入統(tǒng)一寫(xiě)到一個(gè)JS文件中
app.js
插佛。
// 入口文件
// 模塊引入
import * as m1 from '../js/m1.js';
import * as m2 from '../js/m2.js';
import * as m3 from '../js/m3.js';
- 在頁(yè)面文件引入,
app.js
并將script
的類(lèi)型設(shè)置為module
量窘。
<!--類(lèi)型需要設(shè)置成module-->
<script src="../js/app.js" type="module"></script>
ES6 中使用babel對(duì)ES6模塊化代碼進(jìn)行轉(zhuǎn)換使其通用
步驟
安裝工具:
babel-cli
雇寇、babel-preset-env
(預(yù)設(shè)包)、browserify (webpack)
(打包工具)蚌铜。使用該安裝命令 :
npm i babel-cli babel-preset-env browserify -D
進(jìn)行安裝锨侯。執(zhí)行
babel
命令(非全局安裝使用npx):npx babel js -d dist/js --presets=babel-preset-env
。打包:
npx browserify dist/js/app.js -o dist/bundle.js
厘线。
ES6模塊化規(guī)范和NPM包的使用
- 使用
npm
命令安裝jquery
:npm i jquery
;
3. ES7 新特性
3.1 Array.prototype.includes
-
Includes
方法用來(lái)檢測(cè)數(shù)組中是否包含某個(gè)元素识腿,返回布爾類(lèi)型值。和原來(lái)數(shù)組中的indexOf()
方法進(jìn)行區(qū)分造壮。indexOf()
返回的值是元素的位置渡讼,而includes
方法返回的是true
或者false
骂束。
// includes
const four = ['西游記','紅樓夢(mèng)','三國(guó)演義','水滸傳'];
// 判斷
console.log(four.includes('西游記')); // true
console.log(four.includes('金畫(huà)畫(huà)')); // false
// indexOf
console.log(four.indexOf('西游記')); // 0
console.log(four.indexOf('水滸傳')); // 3
console.log(four.indexOf('金畫(huà)畫(huà)')); // -1
3.2 指數(shù)操作符(冪運(yùn)算)
- 在
ES7
中引入指數(shù)運(yùn)算符「**」
,用來(lái)實(shí)現(xiàn)冪運(yùn)算成箫,功能與Math.pow
結(jié)果相同如210展箱。
// 冪運(yùn)算 **
console.log((2 ** 10)); // 1024
console.log(Math.pow(2, 10)); // 1024
4. ECMASript 8 新特性
4.1 async 和 await
-
async
和await
兩種語(yǔ)法結(jié)合可以讓異步代碼像同步代碼一樣。
async 函數(shù)
async
函數(shù)的返回值為promise
對(duì)象蹬昌;promise
對(duì)象的結(jié)果由async
函數(shù)執(zhí)行的返回值決定混驰。
/**
* async(異步的) 修飾的函數(shù)返回的是一個(gè) promise 對(duì)象
* 1. 返回的結(jié)果不是一個(gè)Promise類(lèi)型的對(duì)象 就是一個(gè)成功的Promise;
* 2. 拋出錯(cuò)誤 返回的結(jié)果是一個(gè)失敗的Promise;
* 3. 如果返回的結(jié)果是一個(gè)Promise對(duì)象 ;
*/
async function fun() {
// 1. 返回的結(jié)果不是一個(gè)Promise對(duì)象
// return '我是字符串';
// 2. 返回的結(jié)果中拋出異常
// throw new Error('這是一個(gè)錯(cuò)誤!');
// 3. 返回的結(jié)果是一個(gè)Promise對(duì)象
return new Promise((resolve, reject) => {
// resolve('成功!');
reject('拒絕!');
})
}
const result = fun();
console.log(result);
/**
* 處理結(jié)果
*/
result.then(
value => {
console.log(value);
},
reason => {
console.log(reason);
});
4.2 await 表達(dá)式
await
必須寫(xiě)在async
函數(shù)中;await
右側(cè)的表達(dá)式一般為promise
對(duì)象皂贩;await
返回的是promise
成功的值栖榨;await
的promise
失敗了, 就會(huì)拋出異常, 需要通過(guò)try...catch
捕獲處理。
const p = new Promise((resolve, reject) => {
// resolve('成功的值!');
reject('失敗了!'); // 如果這里失敗 在async 中的await需要使用 try...catch() 捕獲
});
/**
* await 需要放在 async 函數(shù)中
*/
async function mainFun() {
try {
let result = await p;
console.log(result);
} catch (e) {
console.log(e); // 失敗了! 是這里打印的哦
}
}
// 調(diào)用函數(shù)
mainFun();
async 和 await 讀取多個(gè)文件
需要node環(huán)境的支持明刷。
運(yùn)行時(shí)只需要在命令行
node 文件名.js
即可婴栽。
// 引入fs模塊
const fs = require("fs");
// 讀取文件
/**
* 讀取文件 666.md
*/
function rf666() {
return new Promise((resolve, reject) => {
fs.readFile('../resources/666.md', (err, data) => {
if (err) reject(err);
resolve(data);
});
});
}
function rf888() {
return new Promise((resolve, reject) => {
fs.readFile('../resources/888.md', (err, data) => {
if (err) reject(err);
resolve(data);
});
});
}
function rf999() {
return new Promise((resolve, reject) => {
fs.readFile('../resources/999.md', (err, data) => {
if (err) reject(err);
resolve(data);
});
});
}
async function main() {
try {
let f666 = await rf666();
let f888 = await rf888();
let f999 = await rf999();
console.log(f666.toString());
console.log(f888.toString());
console.log(f999.toString());
} catch (e) {
console.log(e);
}
}
main();
async 和 await 封裝ajax請(qǐng)求
/**
* 發(fā)送ajax請(qǐng)求返回的結(jié)果是一個(gè) Promise 對(duì)象
*/
function sendAjax(url) {
return new Promise((resolve, reject) => {
// 1. 創(chuàng)建對(duì)象
const xhr = new XMLHttpRequest();
// 2. 初始化
xhr.open('GET', url);
// 3. 發(fā)送請(qǐng)求
xhr.send();
// 4. 綁定事件
xhr.onreadystatechange = function () {
// 判斷
if (xhr.readyState === 4) { // 需要加上這句狀態(tài)的判斷否則請(qǐng)求不到數(shù)據(jù)
// 判斷狀態(tài)碼 處于 200 - 299 之間
if (xhr.status >= 200 && xhr.status <= 299) {
// 表示成功
// console.log(xhr.response);
// 表示成功
resolve(xhr.response);
} else {
// console.log(xhr.status);
reject(xhr.status);
}
}
};
});
}
console.log(sendAjax('https://api.apiopen.top/getJoke'));
/**
* 使用then處理
*/
sendAjax('https://api.apiopen.top/getJoke').then(value => {
// console.log(value);
}, reason => {
console.log(reason);
});
// 使用 async 和 await 進(jìn)行處理
async function main() {
let joke = await sendAjax('https://api.apiopen.top/getJoke');
console.log(joke);
}
main();
4.2 Object.values 和 Object.entries 、Object.keys()對(duì)象方法擴(kuò)展
Object.values()
方法返回一個(gè)給定對(duì)象的所有可枚舉屬性值的數(shù)組辈末;
Object.entries()
方法返回一個(gè)給定對(duì)象自身可遍歷屬性[key,value]
的數(shù)組愚争;
Object.keys()
方法返回一個(gè)給定對(duì)象的所有可枚舉的屬性。
4.3 Object.getOwnPropertyDescriptors
該方法返回指定對(duì)象所有自身屬性的描述對(duì)象
5. ECMASript 9 新特性
5.1 Rest/Spread 屬性
-
Rest
參數(shù)與spread
擴(kuò)展運(yùn)算符在 ES6 中已經(jīng)引入挤聘,不過(guò) ES6 中只針對(duì)于數(shù)組轰枝,
在ES9 中為對(duì)象
提供了像數(shù)組一樣的 rest 參數(shù)和擴(kuò)展運(yùn)算符
/**
* 對(duì)象的擴(kuò)展運(yùn)算符
*/
const connectCfg = {
host: '127.0.0.1',
port: '3306',
username: 'root',
password: 'root',
type: 'db'
}
/**
* 對(duì)象的展開(kāi)
* @param host
* @param port
* @param user
*/
function connect({host, port, ...user}) {
console.log(host);
console.log(port);
console.log(user);
}
connect(connectCfg);
const skillOne = {
q: '天音波'
};
const skillTwo = {
w: '金鐘罩'
};
const skillThree = {
e: '天雷破'
};
const skillFour = {
r: '猛龍擺尾'
};
// 將對(duì)象拆分為 數(shù)組
const ms = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};
console.log(ms);
5.2 正則擴(kuò)展-命名捕獲分組
- ES9 允許命名捕獲組使用符號(hào)『?<name>』 ,這樣獲取捕獲結(jié)果可讀性更強(qiáng)。
// 聲明一個(gè)字符串
let str = '<a
// 編寫(xiě)正則
let reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result);
console.log(result.groups.url);
console.log(result.groups.text);
5.3 正則擴(kuò)展-反向斷言
- ES9 支持反向斷言组去,通過(guò)對(duì)匹配結(jié)果前面的內(nèi)容進(jìn)行判斷鞍陨,對(duì)匹配進(jìn)行篩選。
/**
* 1. 正向斷言
*
* 2. 反向斷言
*
*/
// 正向斷言
let str = 'zhangsan1235656哈哈哈哈'
const reg = /\d+(?=哈)/;
const result = reg.exec(str);
console.log(result);
// 反向斷言 : 可以根據(jù)前邊的內(nèi)容做判斷
const rg = /(?<=n)\d+/;
console.log(rg.exec(str));
5.4 正則擴(kuò)展dot-All
- 正則表達(dá)式中點(diǎn).匹配除回車(chē)外的任何單字符从隆,標(biāo)記『s』 改變這種行為湾戳,允許行終止符出現(xiàn)。
let str =
'<ul>
<li>
<a>肖申克的救贖</a>
<p>上映時(shí)間:2019</p>
</li>
<li>
<a>阿甘正傳</a>
<p>上映時(shí)間:2018</p>
</li>
</ul>';
/**
* dot . 元字符 除換行符以外的任意單個(gè)字符
*
* 多了一個(gè)模式修正符 s
*
* g 全局修飾符
*/
let reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
let result;
let data = [];
while (result = reg.exec(str)) {
data.push({title: result[1], time: result[2]});
}
console.log(data);
6. ES10 新特性
6.1 Object.fromEntries 和 Object.entries
Object.fromEntries
將數(shù)組轉(zhuǎn)換為對(duì)象广料。
Object.entries
將對(duì)象轉(zhuǎn)換為數(shù)組砾脑。
// 二維數(shù)組
const result = Object.fromEntries([
['name', '仙桃大數(shù)據(jù)學(xué)院'],
['subject', 'Java、前端']
]);
let map = new Map();
map = Object.fromEntries(result);
console.log(map);
6.1 trimEnd() 和 trimStart()
trimEnd()
清除尾部的空白艾杏。
trimStart()
清除首部的空白韧衣。
6.2 flat 和 flatMap
flat
將多維數(shù)組轉(zhuǎn)換為低維數(shù)組 ,參數(shù)傳遞的是代表 深度购桑。
flatMap
類(lèi)似于數(shù)組的map
方法畅铭。map()方法創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素是調(diào)用一次提供的函數(shù)后的返回值勃蜘。參考網(wǎng)址