ECMAScript 6 新特性(二)

ECMAScript 6 新特性(二)

ECMAScript 6 新特性(一)

ECMAScript 6 新特性(二)(本文)

ECMAScript 7~10 新特性

1. 生成器

生成器函數是 ES6 提供的一種解決異步編程方案,一種特殊的函數,語法行為與傳統函數完全不同。

function* gen() {yield 1; // yield 關鍵字用來暫停函數的執行yield 2;yield 3;
}let iterator = gen();
// 調用
// console.log(iterator); // 不能調用
// iterator.next(); // 正常調用// for (let v of gen()) {
//     console.log(v); // 每次返回一個 yield 的值
// }
// 等同于
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

代碼說明:

  1. * 的位置沒有限制;
  2. 生成器函數返回的結果是迭代器對象,調用迭代器對象的 next 方法可以得到 yield 語句后的值;
  3. yield 相當于函數的暫停標記,也可以認為是函數的分隔符,每調用一次 next 方法,執行一段代碼;
  4. next 方法可以傳遞實參,作為 yield 語句的返回值 。

1.1 生成器函數參數

function* gen(arg) {console.log(arg);let one = yield 1;console.log(one);let two = yield 2;console.log(two);let three = yield 3;console.log(three);
}let iterator = gen("aaaaa");
console.log(iterator.next());
// next 方法可以傳入實參,傳入參數會被賦值給 yield 表達式的值
console.log(iterator.next("BBB"));
console.log(iterator.next("CCC"));
console.log(iterator.next('DDD'));

1.2 實例

  1. 1s后控制臺輸出111,2s后輸出222,3s后輸出333

    傳統實現

    setTimeout(() => {console.log("111");setTimeout(() => {console.log("222");setTimeout(() => {console.log("333");}, 3000);}, 2000);
    }, 1000);
    

    代碼較為復雜,不易擴展,使用生成器函數實現

    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. 模擬獲取用戶數據、訂單數據、商品數據

    function getUsers() {setTimeout(() => {let data = "用戶數據";// 調用 next 方法,并將數據傳入iterator.next(data);}, 1000);
    }
    function getOrders() {setTimeout(() => {let data = "訂單數據";iterator.next(data);}, 1000);
    }
    function getGoods() {setTimeout(() => {let data = "商品數據";iterator.next(data);}, 1000);
    }function* genData() {let users = yield getUsers();console.log(users);let orders = yield getOrders();console.log(orders);let goods = yield getGoods();console.log(goods);
    }// 調用生成器函數
    let iterator = genData();
    iterator.next();
    

2. Promise

Promise 是 ES6 引入的異步編程的新解決方案。語法上 Promise 是一個構造函數,用來封裝異步操作并可以獲取其成功或失敗的結果。

  1. Promise 構造函數:Promise (excutor) {}
  2. Promise.prototype.then 方法;
  3. Promise.prototype.catch 方法。

2.1 then 方法

實例化 Promise 時,使用回調函數作為參數,回調函數通常有兩個參數:

  1. resolve 參數

    當執行到 resolve( ... ) 時,會調用 then 方法中的第一個參數(回調);

  2. reject 參數

    當執行到 reject( ... ) 時,會調用 then 方法中的第二個參數(回調);

then 方法中通常有兩個回調函數作為參數,第一個回調在成功時(resolve)調用,第二個回調在出錯時(reject)調用,第二個參數可以省略。

基本使用

// 實例化 Promise 對象
const p = new Promise((resolve, reject) => {setTimeout(() => {let data = "Hello, world!";// resolve(data); // 調用 then 方法中第一個回調reject(new Error("出錯了")); // 調用 then 方法中第二個回調}, 1000);
});// 調用 Promise 對象的 then 方法
p.then((value) => {console.log(value);}, // 成功回調(reason) => {console.error(reason);} // 失敗回調
);

下面列舉幾個使用 Promise 進行封裝的案例:

2.1.1 讀取文件
// 引入模塊
const fs = require("fs");// 使用Promise 封裝
const p = new Promise((resolve, reject) => {fs.readFile("./resources/為學.md", (err, data) => {// 如果失敗,則拋出錯誤if (err) reject(err);// 否則,打印文件內容resolve(data);});
});p.then((value) => {console.log(value.toString());},(reason) => {console.log("出錯了:" + reason);}
);
2.1.2 發送 AJAX 請求
// 封裝 Promise 對象
const p = new Promise((resolve, reject) => {// 1. 創建對象const xhr = new XMLHttpRequest();// 2. 初始化xhr.open("GET", "https://dog.ceo/api/breeds/image/random");// 3. 發送xhr.send();// 4. 綁定事件,處理響應結果xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.responseText);} else {reject(xhr.statusText);}}};
});// 指定回調
p.then((data) => {console.log(data);},(error) => {console.log(error);}
);
2.1.3 Promise.prototype.then
// 創建 Promise 對象
const p = new Promise((resolve, reject) => {resolve("用戶數據");// reject("出錯了");
});const result = p.then((data) => {console.log(data);},(error) => {console.warn(error);}
);console.log(result);
2.1.4 說明

調用 then 方法的返回結果是 Promise 對象,對象狀態由回調函數的執行結果決定

  1. 返回結果是非 Promise 類型的屬性

    返回狀態 resolved(成功),返回值為對象成功的值

    const result = p.then((data) => {console.log(data);return 123;},(error) => {console.warn(error);}
    );console.log(result); // 返回值為 123
    

    如果未使用 return 進行返回,則返回值為 undefined。

  2. 返回 Promise 對象

    返回值和返回狀態均由返回的 promise 對象的返回值和狀態決定

    const result = p.then((data) => {console.log(data);return new Promise((resolve, reject) => {resolve("ok");// reject("出錯了");});},(error) => {console.warn(error);}
    );
    console.log(result); // 返回狀態為 resolved,返回值為 ok
    // console.log(result); // 返回狀態為 rejected,返回值為 出錯了
    
  3. 拋出錯誤

    返回狀態 rejected(失敗)

    const result = p.then((data) => {console.log(data);// throw new Error("出錯了");throw "出錯了";},(error) => {console.warn(error);}
    );console.log(result); // 返回狀態為 rejected,返回值為 出錯了
    

由于 promise 可以返回 promise 對象,因此可以進行鏈式調用

// 鏈式調用
p.then((data) => {},(error) => {}
).then((data) => {},// 失敗回調可以省略
)...;

同時避免的回調地域的問題

2.2 catch 方法

指定 Promise 對象失敗的回調

const p = new Promise((resolve, reject) => {setTimeout(() => {reject("出錯了");}, 1000);
});p.catch((err) => {console.log(err); // 輸出 "出錯了"
});

3. Set

ES6 提供了新的數據結構 Set(集合)。它類似于數組,但成員的值都是唯一的,集合實現了 iterator 接口,所以可以使用擴展運算符for…of… 進 行遍歷,集合的屬性和方法:

  1. size 返回集合的元素個數
  2. add 增加一個新元素,返回當前集合
  3. delete 刪除元素,返回 boolean 值
  4. has 檢測集合中是否包含某個元素,返回 boolean 值
  5. clear 清空集合,返回 undefined
// 聲明一個 set
let s1 = new Set();
let s2 = new Set([1, 2, 3, 4, 5]);console.log(s1, typeof s1); // Set(0) {} object
console.log(s2, typeof s2);// 元素個數
console.log(s2.size); // 5
// 添加元素
s2.add(6);
console.log(s2); // Set(6) {1, 2, 3, 4, 5, 6}
// 刪除元素
s2.delete(1);
console.log(s2); // Set(5) {2, 3, 4, 5, 6}
// 判斷元素是否存在
console.log(s2.has(2)); // true
console.log(s2.has(7)); // false
// 清空集合
s2.clear();
console.log(s2); // Set(0) {}

4. Map

ES6 提供了 Map 數據結構。它類似于對象,也是鍵值對的集合。但是“鍵” 的范圍不限于字符串,各種類型的值(包括對象)都可以當作鍵。Map 也實現了 iterator 接口,所以可以使用擴展運算符for…of… 進行遍歷。Map 的屬 性和方法:

  1. size 返回 Map 的元素個數
  2. set 增加一個新元素,返回當前 Map
  3. get 返回鍵名對象的鍵值
  4. has 檢測 Map 中是否包含某個元素,返回 boolean 值
  5. clear 清空集合,返回 undefined
// 聲明 map
let m = new Map();// 向 map 中添加鍵值對
m.set("name", "張三");
m.set("change", () => {console.log("change");
});
m.set({ age: 25 }, ["李四"]);
// size
console.log(m.size);
// 刪除
m.delete("name");
// 獲取
console.log(m.get("change"));
// 清空
m.clear();console.log(m);

5. Class

ES6 提供了更接近傳統語言的寫法,引入了 Class(類)這個概念,作為對象的模板。通過 class 關鍵字,可以定義類。基本上,ES6 的 class 可以看作只是一個語法糖,它的絕大部分功能,ES5 都可以做到,新的 class 寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。

知識點:

  1. class 聲明類

    class 類名 {屬性 =;...方法() {...}
    }
    
  2. constructor 定義構造函數初始化

    class 類名 {// 構造方法,實例化時自動調用constructor(參數1, 參數2) {this.屬性1 = 參數1;this.屬性2 = 參數2;}... // 屬性、方法
    }// 實例化對象
    let 對象 = new 類名(參數1, 參數2);
    
  3. extends 繼承父類

    class 父類 {...
    }class 子類 extends 父類 {...
    }
    
  4. super 調用父級構造方法

    class 父類 {constructor(參數1, 參數2) {this.屬性1 = 參數1;this.屬性2 = 參數2;}
    }class 子類 extends 父類 {constructor(參數1, 參數2, 參數3, 參數4) {super(參數1, 參數2); // 繼承父類的構造方法// 子類的屬性this.屬性1 = 參數3;}
    }
    
  5. static 定義靜態方法和屬性

    class 類名 {static 屬性 =;static 方法() {...}
    }
    

    靜態屬性和方法不能被讀取和繼承。

  6. 子類重寫父類方法

    子類中可以聲明一個跟父類同名的方法

    class 父類 {方法() {...}
    }class 子類 extends 父類 {// 重寫父類中的同名方法方法() {...}
    }
    

5.1 get 和 set

class Phone {get price() {console.log("價格屬性被讀取");return 3999}set price(value) {console.log("價格屬性被修改");}
}let p = new Phone();console.log(p.price);
p.price = "free";

6. 數值擴展

Number.EPSILON 是 JavaScript 的最小精度,即 2.220446049250313e-16。

當兩個數的差值小于該值,就可以認為這兩個數相等,主要用于浮點數的計算

console.log(0.1 + 0.2 === 0.3); // false,因為浮點數計算不精確
console.log(Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON); // true
// 這時就可以認為 0.1 + 0.2 等于 0.3

6.1 二進制、八進制、十六進制

進制前綴
二進制0b
八進制0o
十六進制0x
let a = 0b1010; // 10
let b = 0o777; // 511
let c = 0x1F;  // 31console.log(a, b, c);

6.2 Number 方法

  1. Number.isFinite() 檢查是否為有限數

    console.log(Number.isFinite(Infinity)); // false
    console.log(Number.isFinite(-Infinity)); // false
    console.log(Number.isFinite(NaN)); // false
    console.log(Number.isFinite(0)); // true
    
    • Infinity:無窮大
    • NaN:非數值
  2. Number.isNaN() 檢查是否為NaN

    console.log(Number.isNaN(NaN)); // true
    console.log(Number.isNaN(0)); // false
    
  3. Number.parseInt()Number.parseFloat() 用于將字符串轉換為數字

    let d = "123";
    let e = "123.456";
    let f = "0b1010";console.log(Number.parseInt(d)); // 123
    console.log(Number.parseFloat(e)); // 123.456
    console.log(Number.parseInt(f)); // 0
    

    這兩個方法都會忽略字符串開頭的空格,并且只解析到第一個非數字字符為止。

  4. Number.isInteger() 檢查是否為整數

    console.log(Number.isInteger(123)); // true
    console.log(Number.isInteger(123.456)); // false
    
  5. Math.trunc() 用于截斷小數部分,返回整數部分

    let i = 123.456;
    let j = -123.456;console.log(Math.trunc(i)); // 123
    console.log(Math.trunc(j)); // -123
    
  6. Math.sign() 用于判斷一個數的正負號

    返回值
    正數1
    0
    負數-1
    console.log(Math.sign(5)); // 1
    console.log(Math.sign(-5)); // -1
    console.log(Math.sign(0)); // 0
    

7. 對象方法擴展

  1. Object.is() 判斷兩個值是否完全相等

    console.log(Object.is(120, 121)); // false
    console.log(Object.is(1.1 + 1.2, 2.3)); // true
    

    作用類似于 == 或 ===,但區別在于對 NaN 的判斷

    console.log(Object.is(NaN, NaN)); // true
    console.log(NaN === NaN); // false
    
  2. Object.assign() 用于兩個對象的合并

    const config1 = {host: "localhost",port: 3306,pass: "root",
    };
    const config2 = {host: "www.baidu.com",port: "8080",
    };
    console.log(Object.assign(config1, config2));
    

    合并兩個對象,相同屬性的值,后者覆蓋前者

  3. Object.setPrototypeOf() 設置對象的原型對象

    Object.getPrototypeOf() 獲取對象的原型對象

    const school = {name: "學院",
    };
    const cities = {xiaoqv: ["商丘", "開封", "洛陽"],
    };
    Object.setPrototypeOf(school, cities);
    console.log(school);
    console.log(Object.getPrototypeOf(school));
    

8. 模塊化

模塊化是指將一個大的程序文件,拆分成許多小的文件,然后將小文件組合起來

8.1 模塊化的好處

模塊化的優勢有以下幾點

  1. 防止命名沖突
  2. 代碼復用
  3. 高維護性
    • 開發人員對文件的修改不會產生過多沖突
    • 當某個功能需要修改、更新時,只需要對單個模塊修改即可

8.2 模塊化規范產品

ES6 之前的模塊化規范有:

規范產品
CommonJSNodeJS、Browserify
AMDrequireJS
CMDseaJS

8.3 ES6 模塊化語法

模塊功能主要由兩個命令構成:exportimport

  • export 命令用于規定模塊的對外接口(暴露模塊接口);
  • import 命令用于輸入其他模塊提供的功能(導入其它模塊)。

暴露接口的幾種方式

  1. 默認暴露:export default 接口;

    每個模塊只能有一個默認暴露

    導入:import 接口 from ...;

  2. 命名暴露:export 屬性名/對象名/...;

    命名導出允許你導出多個值,并且每個導出都有一個名稱。

    導入:import { 屬性名/對象名/... } from ...;

  3. 混合暴露:export { 屬性名/對象名/..., 屬性名2/對象名2/... as default };

    在一個模塊中同時使用默認暴露和命名暴露。

    導入:import 屬性名2/對象名2/..., { 屬性名/對象名/... } from ...;

  4. 重新暴露

    可以從一個模塊中導出另一個模塊的導出內容。

    模塊1:export 屬性名/對象名/...;

    模塊2:export { 屬性名/對象名/... } from ...;

    導入:import { 屬性名/對象名/... } from ...;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75324.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75324.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75324.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入理解 RxSwift 中的 Driver:用法與實踐

目錄 前言 一、什么是Driver 1.不會發出錯誤 2.主線程保證 3.可重放 4.易于綁定 二、Driver vs Observable 三、使用場景 1.綁定數據到UI控件 2.響應用戶交互 3.需要線程安全的邏輯 4.如何使用Driver? 1.綁定文本輸入到Label 2.處理按鈕點擊事件 3.從網絡請求…

Linux自行實現的一個Shell(15)

文章目錄 前言一、頭文件和全局變量頭文件全局變量 二、輔助函數獲取用戶名獲取主機名獲取當前工作目錄獲取最后一級目錄名生成命令行提示符打印命令行提示符 三、命令處理獲取用戶輸入解析命令行執行外部命令 四、內建命令添加環境變量檢查和執行內建命令 五、初始化初始化環境…

RocketMQ和kafka 的區別

一、數據可靠性與容錯機制 數據可靠性 RocketMQ支持同步刷盤和同步復制&#xff0c;確保消息寫入磁盤后才返回確認&#xff0c;單機可靠性高達10個9&#xff0c;即使操作系統崩潰也不會丟失數據。而Kafka默認采用異步刷盤和異步復制&#xff0c;雖然吞吐量高&#xff0c;但極端…

在 openEuler 24.03 (LTS) 操作系統上添加 ollama 作為系統服務的步驟

以下是在 openEuler 操作系統上添加 ollama 作為系統服務的步驟&#xff1a; 創建 systemd 服務文件 sudo vi /etc/systemd/system/ollama.service將以下內容寫入服務文件&#xff08;按需修改參數&#xff09;&#xff1a; [Unit] DescriptionOllama Service Afternetwork.…

光譜相機的關鍵技術參數

光譜相機的關鍵技術參數直接影響其數據獲取能力和應用場景適配性。以下是核心參數的詳細解析&#xff0c;涵蓋光譜性能、空間性能、硬件性能及環境適應性&#xff1a; 一、光譜性能參數? ?1. 光譜范圍&#xff08;Spectral Range&#xff09;? ?定義?&#xff1a;相機可…

ARM內核與寄存器

ARM內核與寄存器詳解 目錄 ARM架構概述ARM處理器模式 Cortex-M3內核的處理器模式Cortex-A系列處理器模式 ARM寄存器集 通用寄存器程序計數器(PC)鏈接寄存器(LR)堆棧指針(SP)狀態寄存器(CPSR/SPSR) 協處理器寄存器NEON和VFP寄存器寄存器使用規范常見ARM指令與寄存器操作 ARM架…

Git 拉取時常見沖突及解決方法總結

Git 拉取時常見沖突及解決方法總結 一、常見錯誤場景1. 本地修改與遠程修改沖突解決方法 2. 未跟蹤文件與遠程文件沖突解決方法 3. 子模塊權限問題解決方法 二、總結 在日常開發中&#xff0c;使用 Git 進行團隊協作和代碼管理時&#xff0c;經常會遇到拉取代碼&#xff08;git…

深度學習、圖像算法學習記錄

深度學習加速 綜述文檔&#xff1a; https://chenzomi12.github.io/02Hardware01Foundation/02ArchSlim.html winograd: https://zhuanlan.zhihu.com/p/260109670 ncnn 1.修改模型結構&#xff0c;優化模型內存訪問次數&#xff0c;加速。 VGG 和 InceptionNet &#xff1a; …

Java中的Exception和Error有什么區別?還有更多擴展

概念 在Java中&#xff0c;Exception和Error都是Throwable的子類&#xff0c;用于處理程序中的錯誤和異常情況。 然而&#xff0c;它們在用途和處理方式上有顯著的不同&#xff1a; Exception&#xff1a; 用于表示程序在正常運行過程中可能出現的錯誤&#xff0c;如文件未找…

文章記單詞 | 第26篇(六級)

一&#xff0c;單詞釋義 actor&#xff1a;名詞&#xff0c;演員mask&#xff1a;名詞&#xff0c;面具&#xff1b;口罩&#xff1b;遮蓋物&#xff1b;動詞&#xff0c;掩飾&#xff1b;戴面具&#xff1b;遮蓋construct&#xff1a;動詞&#xff0c;建造&#xff1b;構造&a…

LeetCode算法題(Go語言實現)_38

題目 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。 一、代碼實現 type TreeNode struct {Val intLeft *TreeNodeRight *TreeNode }func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {if root nil || root p || root q {return root}left : lowes…

Java 基礎語法、Java注釋

Java 基礎語法 一個 Java 程序可以認為是一系列對象的集合,而這些對象通過調用彼此的方法來協同工作。下面簡要介紹下類、對象、方法和實例變量的概念。 對象:對象是類的一個實例,有狀態和行為。例如,一條狗是一個對象,它的狀態有:顏色、名字、品種;行為有:搖尾巴、叫…

用VScode來編寫前后端——構建基礎框架

前言 我寫這一個板塊的原因是我參加了我們學校的新生項目課&#xff0c;需要創立一個系統&#xff0c;我們小組選的標題的基于計算機視覺的商品識別系統&#xff0c;那么我們需要一個網站來展示我們的功能&#xff0c;故寫這些來記錄一下自己&#xff0c;大家如果有什么問題的話…

git clone阻塞問題

問題描述 git clone采用的ssh協議&#xff0c;在克隆倉庫的時候&#xff0c;會經常卡一下&#xff0c;亦或是直接卡死不動。 最開始以為是公司電腦配置的問題&#xff0c;想著自己實在解決不了找it幫忙。 查閱資料發現&#xff0c;最終發現是git版本的問題&#xff0c;這個是…

WEB攻防-Java安全JNDIRMILDAP五大不安全組件RCE執行不出網不回顯

目錄 1. RCE執行-5大類函數調用 1.1 Runtime方式 1.2 Groovy執行命令 1.3 腳本引擎代碼注入 1.4 ProcessImpl 1.5 ProcessBuilder 2. JNDI注入(RCE)-RMI&LDAP&高版本 2.1 RMI服務中的JNDI注入場景 2.2 LDAP服務中的JNDI注入場景 攻擊路徑示例&#…

【Hadoop入門】Hadoop生態之Sqoop簡介

1 什么是Sqoop&#xff1f; 在企業的數據架構中&#xff0c;關系型數據庫與Hadoop生態系統之間的數據流動是常見且關鍵的需求。Apache Sqoop&#xff08;SQL-to-Hadoop&#xff09;正是為解決這一問題而生的高效工具&#xff0c;它專門用于在結構化數據存儲&#xff08;如RDBMS…

如何自動檢測使用的組件庫有更新

&#x1f916; 作者簡介&#xff1a;水煮白菜王&#xff0c;一位前端勸退師 &#x1f47b; &#x1f440; 文章專欄&#xff1a; 前端專欄 &#xff0c;記錄一下平時在博客寫作中&#xff0c;總結出的一些開發技巧和知識歸納總結?。 感謝支持&#x1f495;&#x1f495;&#…

Go語言編寫一個進銷存Web軟件的demo

Go語言編寫一個進銷存Web軟件的demo 用戶現在要求用。之前他們已經討論了用Django實現的方案&#xff0c;現在突然切換到Go&#xff0c;可能有幾個原因。首先&#xff0c;用戶可能對Go語言感興趣&#xff0c;或者他們公司的技術棧轉向了Go。其次&#xff0c;用戶可能希望比較不…

【前綴和】矩陣區域和(medium)

矩陣區域和&#xff08;medium&#xff09; 題?描述&#xff1a;解法&#xff1a;代碼Java 算法代碼&#xff1a;C 算法代碼&#xff1a; 題?描述&#xff1a; 題?鏈接&#xff1a;1314. 矩陣區域和 給你?個 m x n 的矩陣 mat 和?個整數 k &#xff0c;請你返回?個矩陣 …

Java學習手冊:Java發展歷史與版本特性

Java作為全球最流行的編程語言之一&#xff0c;其發展歷程不僅見證了技術的演進&#xff0c;也反映了軟件開發模式的變革。從1995年的首次發布到如今的持續更新&#xff0c;Java始終保持著強大的生命力和廣泛的影響力。本文將簡要回顧Java的發展歷程&#xff0c;并重點介紹其關…