ECMAScript6入门教程(二)
ECMAScript入門教程(一)
2.11 生成器
生成器函數是 ES6 提供的一種異步編程解決方案,語法行為與傳統函數完全不同
? ? ? ?function * gen(){yield '一只沒有耳朵';yield '一只沒有尾部';yield '真奇怪';} ?let iterator = gen();console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next()); ?//遍歷for(let v of gen()){console.log(v);}代碼說明:
1) * 的位置沒有限制
2) 生成器函數返回的結果是迭代器對象,調用迭代器對象的 next 方法可以得到yield 語句后的值
3) yield 相當于函數的暫停標記,也可以認為是函數的分隔符,每調用一次 next方法,執行一段代碼
4) next 方法可以傳遞實參,作為 yield 語句的返回值
? ? ? ?function * gen(arg){console.log(arg);let one = yield 111;console.log("one:"+one);let two = yield 222;console.log("two:"+two);let three = yield 333;console.log("three:"+three);} ?//執行獲取迭代器對象let iterator = gen('AAA');console.log(iterator.next());//next方法可以傳入實參console.log(iterator.next('BBB'));console.log(iterator.next('CCC'));console.log(iterator.next('DDD'));打印如下:
?
案例:1s 后控制臺輸出 111, 2s后輸出 222 ,3s后輸出 333
? ? ? ?function one(){setTimeout(()=>{console.log(111);iterator.next();},1000)} ?function two(){setTimeout(()=>{console.log(222);iterator.next();},2000)} ?function three(){setTimeout(()=>{console.log(333);iterator.next();},3000)} ?function * gen(){yield one();yield two();yield three();} ?//調用生成器函數let iterator = gen();iterator.next();2.12 Promise
Promise 是 ES6 引入的異步編程的新解決方案。語法上 Promise 是一個構造函數,用來封裝異步操作并可以獲取其成功或失敗的結果。
1) Promise 構造函數: Promise (excutor) {}
2) Promise.prototype.then 方法
3) Promise.prototype.catch 方法
? ? ? ?//實例化 Promise 對象const p = new Promise(function(resolve, reject){setTimeout(function(){ ?// let data = '數據庫中的用戶數據';// resolve(data); ?let err = '數據讀取失敗';reject(err);}, 1000);}); ?//調用 promise 對象的 then 方法 // resolve代表成功,調用then里面的第一個函數,reject代表失敗,調用then里面的第二個函數p.then(function(value){console.log(value);}, function(reason){console.error(reason);})我們使用Promise實現異步讀取文件的操作:
//1. 引入 fs 模塊 const fs = require('fs'); ? //2. 使用 Promise 封裝 const p = new Promise(function(resolve, reject){fs.readFile("./resources/為學.mda", (err, data)=>{//判斷如果失敗if(err) reject(err);//如果成功resolve(data);}); }); ? p.then(function(value){console.log(value.toString()); }, function(reason){console.log("讀取失敗!!"); }); ? // p.catch(function(reason){ // ? ? console.warn(reason); // }); ? // 使用node命令執行: node xxx.js我們使用Promise封裝ajax發送請求:
? ?//實例化 Promise 對象const p = new Promise(function (resolve, reject) {setTimeout(function () { ?// let data = '數據庫中的用戶數據';// resolve(data); ?let err = '數據讀取失敗';reject(err);}, 1000);}); ?//調用 promise 對象的 then 方法// resolve代表成功,調用then里面的第一個函數,reject代表失敗,調用then里面的第二個函數p.then(function(value){console.log(value);}, function(reason){console.error(reason);})// p.catch(function (reason) {// ? ? console.error(reason)// })使用then()可以實現循環嵌套
//引入 fs 模塊 const fs = require("fs"); ? // fs.readFile('./resources/為學.md', (err, data1)=>{ // ? ? fs.readFile('./resources/插秧詩.md', (err, data2)=>{ // ? ? ? ? fs.readFile('./resources/觀書有感.md', (err, data3)=>{ // ? ? ? ? ? ? let result = data1 + '\r\n' +data2 +'\r\n'+ data3; // ? ? ? ? ? ? console.log(result); // ? ? ? ? }); // ? ? }); // }); ? //使用 promise 實現 const p = new Promise((resolve, reject) => {fs.readFile("./resources/為學.md", (err, data) => {resolve(data);}); }); ? p.then(value => {return new Promise((resolve, reject) => {fs.readFile("./resources/插秧詩.md", (err, data) => {resolve([value, data]);});}); }).then(value => {return new Promise((resolve, reject) => {fs.readFile("./resources/觀書有感.md", (err, data) => {//壓入value.push(data);resolve(value);});}) }).then(value => {console.log(value.join('\r\n')); });2.13 Set
ES6 提供了新的數據結構 Set(集合)。它類似于數組,但成員的值都是唯一的,集合實現了 iterator 接口,所以可以使用『擴展運算符』和『for…of…』進行遍歷,集合的屬性和方法:
? ?//聲明一個 setlet s2 = new Set(['大事兒', '小事兒', '好事兒', '壞事兒', '小事兒']); ?//元素個數console.log(s2.size);//添加新的元素s2.add('喜事兒');//刪除元素s2.delete('壞事兒');//檢測console.log(s2.has('糟心事'));//清空// s2.clear();console.log(s2); ?for (let v of s2) {console.log(v);}我們可以用Set來求數組的去重、交集、并集、差集
? ?let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];//1. 數組去重let result = [...new Set(arr)];console.log(result);//2. 交集let arr2 = [4, 5, 6, 5, 6];let result2 = [...new Set(arr)].filter(item => {return new Set(arr2).has(item);});console.log(result2); ?//3. 并集let union = [...new Set([...arr, ...arr2])];console.log(union); ?//4. 差集let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));console.log(diff); ?2.14 Map
ES6 提供了 Map 數據結構。它類似于對象,也是鍵值對的集合。但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當作鍵。Map 也實現了iterator 接口,所以可以使用『擴展運算符』和『for…of…』進行遍歷。Map 的屬性和方法:
? ?//聲明 Maplet m = new Map(); ?//添加元素m.set('name', '進擊的巨人');m.set('change', function () {console.log("為人類獻出心臟!!");});let key = {school: '史萊克學院'};m.set(key, ['唐三', '小舞', '戴沐白']); ?//sizeconsole.log(m.size); ?//刪除m.delete('name'); ?//獲取console.log(m.get('change'));console.log(m.get(key)); ?//清空// m.clear(); ?//遍歷for (let v of m) {console.log(v);} ?console.log(m);2.15 class類
ES6 提供了更接近傳統語言的寫法,引入了 Class(類)這個概念,作為對象的模板。通過 class 關鍵字,可以定義類。基本上,ES6 的 class 可以看作只是一個語法糖,它的絕大部分功能,ES5 都可以做到,新的 class 寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。
-
class 聲明類
-
constructor 定義構造函數初始化
-
extends 繼承父類
-
super 調用父級構造方法
-
static 定義靜態方法和屬性
-
父類方法可以重寫
靜態屬性/方法的案例演示:
? ?class Phone {//靜態屬性static name = '手機'; ?static change() {console.log("我可以改變世界");}} ?let nokia = new Phone();console.log(nokia.name);console.log(Phone.name);繼承/方法重寫案例演示:
? ?class Phone {//構造方法constructor(brand, price) {this.brand = brand;this.price = price;} ?//父類的成員屬性call() {console.log("我可以打電話!!");}} ?class SmartPhone extends Phone {//構造方法constructor(brand, price, color, size) {super(brand, price);// Phone.call(this, brand, price)this.color = color;this.size = size;} ?photo() {console.log("拍照");} ?playGame() {console.log("玩游戲");} ?// 方法重寫call() {console.log('我可以進行視頻通話');}} ?const xiaomi = new SmartPhone('小米', 799, '黑色', '4.7inch');xiaomi.call();xiaomi.photo();xiaomi.playGame();get/set的案例演示:
? ?// get 和 set ?class Phone {constructor(count, money) {this.count = count;this.money = money;} ?get price() {console.log("價格屬性被讀取了");return this.money * this.count;} ?set price(newVal) {console.log("價格屬性被修改了");this.money = 200;}} ?//實例化對象let s = new Phone(2, 188); ?console.log(s.price);s.price = 88;console.log(s.price);2.16 數值拓展
? ?//0. Number.EPSILON 是 JavaScript 表示的最小精度//EPSILON 屬性的值接近于 2.2204460492503130808472633361816E-16function equal(a, b) {if (Math.abs(a - b) < Number.EPSILON) {return true;} else {return false;}} ?console.log(0.1 + 0.2 === 0.3);console.log(equal(0.1 + 0.2, 0.3)) ?//1. 二進制和八進制let b = 0b1010;let o = 0o777;let d = 100;let x = 0xff;console.log(x); ?//2. Number.isFinite 檢測一個數值是否為有限數console.log(Number.isFinite(100));console.log(Number.isFinite(100 / 0));console.log(Number.isFinite(Infinity)); ?//3. Number.isNaN 檢測一個數值是否為 NaN console.log(Number.isNaN(123)); ?//4. Number.parseInt Number.parseFloat字符串轉整數console.log(Number.parseInt('5211314love'));console.log(Number.parseFloat('3.1415926神奇')); ?//5. Number.isInteger 判斷一個數是否為整數console.log(Number.isInteger(5));console.log(Number.isInteger(2.5)); ?//6. Math.trunc 將數字的小數部分抹掉 ?console.log(Math.trunc(3.5)); ?//7. Math.sign 判斷一個數到底為正數 負數 還是零console.log(Math.sign(100));console.log(Math.sign(0));console.log(Math.sign(-20000));2.17 對象擴展
ES6 新增了一些 Object 對象的方法
1) Object.is 比較兩個值是否嚴格相等,與『===』行為基本一致(+0 與 NaN)
2) Object.assign 對象的合并,將源對象的所有可枚舉屬性,復制到目標對象
3) proto、setPrototypeOf、 setPrototypeOf 可以直接設置對象的原型
? ?//1. Object.is 判斷兩個值是否完全相等 與『===』行為基本一致(+0 與 NaN)console.log(Object.is(120, 120)); ?//trueconsole.log(Object.is(NaN, NaN)); ?//trueconsole.log(NaN === NaN); ? ? ? ? ?//false ?//2. Object.assign 對象的合并const config1 = {host: 'localhost',port: 3306,name: 'root',pass: 'root',test: 'test'};const config2 = {host: '127.0.0.1',port: 33060,name: 'admin',pass: 'admin',test2: 'test2'}console.log(Object.assign(config1, config2)); ?//后者會覆蓋前者 ?//3. Object.setPrototypeOf 設置原型對象 Object.getPrototypeOfconst school = {name: '四大才子'}const member = {people: ['唐伯虎', '祝枝山', '文征明', "徐禎卿"]}Object.setPrototypeOf(school, member);console.log(Object.getPrototypeOf(school));console.log(school);2.18 map和reduce
map
map一般來說針對數組進行操作。但是進行了一個很好的封裝使得讀者可以清晰的看到被操作數組,以及對數組內每個元素進行操作的函數。
reduce
reduce() 方法接收一個函數作為累加器(accumulator),數組中的每個值(從左到右)開始縮減,最終為一個值。
reduce 為數組中的每一個元素依次執行回調函數,不包括數組中被刪除或從未被賦值的元素,接受四個參數:初始值(或者上一次回調函數的返回值),當前元素值,當前索引,調用 reduce 的數組。
語法:
arr.reduce(callback,[initialValue])-
callback (執行數組中每個值的函數,包含四個參數)
-
previousValue (上一次調用回調返回的值,或者是提供的初始值(initialValue))
-
currentValue (數組中當前被處理的元素)
-
index (當前元素在數組中的索引)
-
array (調用 reduce 的數組)
-
-
initialValue (作為第一次調用 callback 的第一個參數。)
3.模塊化
3.1 模塊化的好處
-
防止命名沖突
-
代碼復用
-
高維護性
3.2 模塊化規劃產品
ES6 之前的模塊化規范有:
CommonJS => NodeJS、Browserify
AMD => requireJS
CMD => seaJS
3.3 模塊化語法
模塊功能主要由兩個命令構成:export 和 import。
-
export 命令用于規定模塊的對外接口
-
import 命令用于輸入其他模塊提供的功能
3.4 export
export有三種寫法,如下為具體示例:
m1.js
//分別暴露 export let school = '清華大學'; ? export function teach() {console.log("自強不息,厚德載物"); }m2.js
//統一暴露 let school = '北京大學'; ? function teach(){console.log("勤奮、嚴謹、求實、創新"); } ? // export {school, teach};m3.js
//默認暴露 export default {school: '中國人民大學',change: function(){console.log("實事求是");} }3.5 import
<script type="module">//1. 通用的導入方式//引入 m1.js 模塊內容import * as m1 from "./src/js/m1.js"; ?console.log(m1);// //引入 m2.js 模塊內容import * as m2 from "./src/js/m2.js"; ?console.log(m2);// //引入 m3.jsimport * as m3 from "./src/js/m3.js"; ?console.log(m3);console.log(m3.default.change()); ?//2. 解構賦值形式import {school, teach} from "./src/js/m1.js";import {school as beida, teach as teach_1} from "./src/js/m2.js"; ?console.log(beida);console.log(teach_1());import {default as m3} from "./src/js/m3.js"; ?//3. 簡便形式 只針對默認暴露import m3_1 from "./src/js/m3.js"; ?console.log(m3_1); </script>3.6 更簡潔的模塊化引入
我們單獨定義一個js文件
//入口文件 ? //模塊引入 import * as m1 from "./m1.js"; import * as m2 from "./m2.js"; import * as m3 from "./m3.js"; ? console.log(m1); console.log(m2); console.log(m3);在我們的html文件中,只需要做如下操作即可引入:
<script src="./src/js/app.js" type="module"></script>?
總結
以上是生活随笔為你收集整理的ECMAScript6入门教程(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ECMAScript6入门教程(一)
- 下一篇: webpack从入门到精通(一)初体验