一.ECMASript 相關介紹
1.1. 什麼是 ECMAScript
ECMAScript 是由 Ecma 國際通過 ECMA-262 標準化的腳本程序設計語言。
1.2. 什麼是 ECMA-262
Ecma 國際制定了許多標準,而 ECMA-262 只是其中的一個
相關地址:http://www.ecma-international.org/publications/standards/Standard.htm
1.3. ECMA-262 歷史
ECMA-262(ECMAScript)歷史版本查看網址:http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm
第1版 |
1997 年 |
制定了語言的基本語法 |
第2版 |
1998 年 |
較小改動 |
第3版 |
1999 年 |
引入正則、異常處理、格 式化輸出等。IE 開始支持 |
第4版 |
2007 年 |
過於激進,未發佈 |
第5版 |
2009 年 |
引入嚴格模式、JSON,擴 展對象、數組、原型、字 符串、日期方法 |
第6版 |
2015年 |
模塊化、面向對象語法、Promise、箭頭函數、let、const、數組解構賦值等等 |
第7版 |
2016 年 |
冪運算符、數組擴展、Async/await 關鍵字 |
第8版 |
2017 年 |
Async/await、字符串擴展 |
第9版 |
2018 年
|
對象解構賦值、正則擴展 |
第10版 |
2019 年 |
擴展對象、數組方法 |
ES.next |
動態指向下一個版本 |
|
特別說明:從 ES6 開始,每年發佈一個版本,版本號比年份最後一位大 1
1.4. ECMA-262是有哪些組織在維護
TC39(Technical Committee 39)是推進 ECMAScript 發展的委員會。其會員都是 公司(其中主要是瀏覽器廠商,有蘋果、谷歌、微軟、因特爾等)。TC39 定期 召開會議,會議由會員公司的代表與特邀專家出席.
1.5. ES6 兼容性
相關地址:http://kangax.github.io/compat-table/es6/ 可以查看es6兼容性
二.ECMASript 6 新特性
2.1 let 關鍵字
- 變量不能重複定義
- 塊兒級作用域
- 不存在變量提升
- 不受作用域鏈影響
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.test {
display: inline-block;
width: 80px;
height: 80px;
border: 1px solid #333;
}
</style>
<body>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div><br>
<button onclick="test()">測試</button>
<script>
var divs = document.getElementsByClassName("test");
// 採用var來定義變量
for (var i = 0; i< divs.length; i++) {
divs[i].onclick=function() {
divs[i].style.background="pink"
}
}
// 上面方式由於變量i作用域是全局的,導致循環結束後i的值變成3,我們只有3個div,這樣通過
// divs[i]取值就會導致越界。可以通過this.style.background="pink"來解決這個問題
// for (let i = 0; i< divs.length;i++) {
// divs[i].onclick=function() {
// divs[i].style.background='pink'
// }
// }
// 第二種方式採用let定義變量,let定義變量是塊兒級作用域,在每次循環體中變量值是獨立不受
// 影響
</script>
</body>
</html>
2.2 const關鍵字
const用來定義一個常量,有如下特點:
- 聲明必須賦值
- 標誌符一般大寫
- 值不允許修改
- 塊兒級作用域
- 不允許重複定義
注意:修改對象中的屬性或者數組中元素變化是不會導致const錯誤。
使用場景:聲明一個對象類型或者常量採用const,否則直接使用let
2.3變量的解構賦值
es6中允許按照一定的模式從對象或者數組提取值給變量賦值,這種方式被稱爲解構賦值。
<script>
//解構數組
let arry = ['aa','bb','cc']
let [a,b,c] = arry
console.log(a)
console.log(b)
console.log(c)
//解構對象
let obj1 = {name:'張三', age:18}
let {name,age}=obj1
console.log(name)
console.log(age)
// 解構複雜對象
let obj2 = {username: '張三', family:{sister:'Lisa'},hoppy:['football','basketball']}
let {username,family:{sister},hoppy:[one,two]}=obj2
console.log(username)
console.log(sister)
console.log(one)
console.log(two)
</script>
注意:如果頻繁使用對象中的方法和數組元素,就可以使用解構賦值,這樣會讓代碼更加簡潔。
2.4 模版字符串
模版字符串是字符串增強版,用反引號(``)標識
- 字符串中可以出現換行符
- 可以在字符串中使用${}方式輸出變量
使用場景:當遇到字符串與變量拼接的時候可以使用模版字符串
2.5 對象簡寫寫法
es6中允許直接在{}裏寫入變量名和方法,作爲對象中屬性和方法,這樣可以簡化對象的寫法
let a = 'aa'
let b = 'bb'
let c = function() {
console.log('這是c方法')
}
let obj = {
a,
b,
c,
d:function(){
console.log('這是d方法')
}
}
console.log(obj)
以後使用完全可以採用簡寫方式來使用對象
2.6箭頭函數
es6中允許採用()=>{}這種方式創建一個函數
let func = () => {
console.log('箭頭函數')
}
- 箭頭函數如果只有一個參數,可以省略小括號
- 如果箭頭函數體中只有一條語句,可以省略花括號,函數體返回的值就是語句執行的結果
- 箭頭函數不能通過構造函數來創建
- 箭頭函數中沒有arguments
- 箭頭函數this指向聲明時所在作用域下this的值
// 1.函數參數只有1個參數,省略()
let func1 = a => {
console.log(a)
}
func1('測試func1')
// 2.函數體中只有一條語句,省略花括號
let func2 = (a,b) => a+b;
console.log(func2(123,456))
// 3.箭頭函數this指向(window)
let func3 = () => {
console.log(this)
}
func3()
使用場景:箭頭函數不會改變this指向,應此非常適合作爲回調函數來使用
2.7 rest參數
es6中引入rest參數來獲取函數的實參,來代替es5中arguments
function func(...args) {
// args是一個數組類型
console.log(args)
args.map(item => console.log(item))
}
func('aa','bb','cc','dd')
func({a:'aa',b:'bb',c:'cc'})
適用場景:適用於去接受不確定的實參個數
2.8 spread擴展運算符
擴展運算符spread(...),它可以將一個數組展開爲用逗號隔開多個參數序列,它被當作rest參數逆向運算。
function func() {
console.log(arguments)
}
// 數組作爲參數來展開
func(['aa',1,true])
// 合併數組
let arry1 = ['aa','bb','cc','dd']
let arry2 = ['11','22','33']
func(...arry1)
console.log([...arry1,...arry2])
// 合併對象
let obj1 = {a:'aa',b:'bb',c:'cc'}
let obj2 = {name:'張三',age:18}
console.log({...obj1,...obj2})
2.9 Symbol
2.9.1 ES6 引入了一種新的原始數據類型 Symbol,表示獨一無二的值。它是JavaScript 語言的第七種數據類型,是一種類似於字符串的數據類型。
- Symbol 的值是唯一的,用來解決命名衝突的問題
- Symbol 值不能與其他數據進行運算
- Symbol 定義的對象屬性不能使用 for...in 循環遍歷,但是可以使用Reflect.ownKeys 來獲取對象的所有鍵名
//添加標識符
let sym = Symbol('測試')
console.log(sym)
console.log(typeof sym)
let sym1 = Symbol('測試')
console.log(sym===sym1) // 返回false
//使用Symbol.for來定義
let sym2 = Symbol.for('測試')
let sym3 = Symbol.for('測試')
console.log(sym2===sym3) // 返回true
注意:當需要使用唯一性就可以採用Symbol
2.9.2 Symbol內置的值
除了定義自己使用的 Symbol 值以外,ES6 還提供了11個內置的Symbol值,指向語言內部使用的方法。
Symbol.hasInstance |
當其他對象使用 instanceof 運算符,判斷是否爲該對 象的實例時,會調用這個方法 |
Symbol.isConcatSpreadable |
對象的 Symbol.isConcatSpreadable 屬性等於的是一個 布爾值,表示該對象用於 Array.prototype.concat()時, 是否可以展開。 |
Symbol.species |
創建衍生對象時,會使用該屬
|
Symbol.match |
當執行 str.match(myObject) 時,如果該屬性存在,會 調用它,返回該方法的返回值。 |
Symbol.replace |
當該對象被 str.replace(myObject)方法調用時,會返回 該方法的返回值。 |
Symbol.search |
當該對象被 str. search (myObject)方法調用時,會返回 該方法的返回值。 |
Symbol.split |
當該對象被 str. split (myObject)方法調用時,會返回該 方法的返回值。 |
Symbol.iterator |
對象進行 for...of 循環時,會調用 Symbol.iterator 方法, 返回該對象的默認遍歷器 |
Symbol.toPrimitive |
該對象被轉爲原始類型的值時,會調用這個方法,返
回該對象對應的原始類型值。
|
Symbol. toStringTag |
在該對象上面調用 toString 方法時,返回該方法的返 回值 |
Symbol. unscopables |
該對象指定了使用with關鍵字時,哪些屬性會被with環境排除。 |
2.10 迭代器
迭代器(iterator)是一種機制,它是一個接口。爲各種不同的數據結構提供了一個統一訪問機制,任何數據只有實現iterator,就可以遍歷數據
- ES6 創造了一種新的遍歷命令 for...of 循環,Iterator 接口主要供 for...of 消費
- 原生具備 iterator 接口的數據(可用 for of 遍歷)
- Array
- Arguments
- Set
- Map
- String
- TypeArray
- NodeList
工作原理:
-
創建一個指針對象,指向當前數據結構的起始位置
-
第一次調用對象的 next 方法,指針自動指向數據結構的第一個成員
-
接下來不斷調用 next 方法,指針一直往後移動,直到指向最後一個成員
-
每調用 next 方法返回一個包含 value 和 done 屬性的對象
let arry = ['let','const','解構賦值','箭頭函數','rest參數','擴展運算符spread']
console.log(arry)
let look = arry[Symbol.iterator]()
console.log(look.next())
let obj = {
name: '張三',
age: 18,
arry: ['aa','bb','cc','dd'],
[Symbol.iterator]() {
let i = 0
let _this = this
return {
next:function(){
if (i < _this.arry.length) {
let result = {value: _this.arry[i],done: false}
i++
return result
} else {
return {value: undefined,done: true}
}
}
}
}
}
for (const item of obj) {
console.log(item)
}
注意: 需要自定義遍歷數據,可以使用迭代器
2.11 生成器
生成器是es6提供一種解決異步編程的方案。
- * 的位置沒有限制
- 生成器函數返回的結果是迭代器對象,調用迭代器對象的 next 方法可以得到yield 語句後的值
- yield 相當於函數的暫停標記,也可以認爲是函數的分隔符,每調用一次 next方法,執行一段代碼。
- next 方法可以傳遞實參,作爲 yield 語句的返回值。
function* gen(args) {
console.log(args)
let one = yield read();
console.log(one)
let two = yield play();
console.log(two)
let three = yield sleep();
console.log(three)
}
let iterator = gen('傳遞參數')
iterator.next()
function read() {
setTimeout(() => {
iterator.next("讀書")
},1000)
}
function play() {
setTimeout(() => {
iterator.next("玩耍")
},2000)
}
function sleep() {
setTimeout(() => {
console.log('睡覺')
},3000)
}
2.12 Promise
promise是es6提供一種解決異步編程的方案,可以獲取成功與失敗的結果。同時可以使用鏈式調用解決地獄回調的問題
- Promise 構造函數: Promise (excutor) {}
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
let promise = new Promise((resolve,reject) => {
resolve('成功');
})
let result = promise.then(value => {
return new Promise((resolve,reject) => {
reject('失敗')
})
},err => {
console.log(err)
}).catch(err => {
console.log(err)
})
console.log(result)
2.13 Set
ES6 提供了新的數據結構 Set(集合)。它類似於數組,但成員的值都是唯 一的,集合實現了 iterator 接口,所以可以使用『擴展運算符』和『for...of...』
進行遍歷。集合中提供方法和屬性:
- size 返回集合個數
- add 向集合中添加數據,返回當前集合
- delete 刪除集合中元素,返回boolean
- has 判斷當前集合中是否含有某個元素,返回boolean
- clean 清空集合,返回undefine
let set = new Set(['a','b','c','d','a','b'])
console.log(set)
console.log(set.size)
let keys = set.keys();
console.log('keys', keys)
for (const item of keys) {
console.log(item)
}
let values = set.values();
console.log('values', values)
for (const item of values) {
console.log(item)
}
//在集合末中添加一條數據
let add = set.add('111')
console.log(add)
//刪除集合中一條數據
let del = set.delete('a')
console.log(del)
// 可以包裹不規則數組(arguments)
let divs = document.getElementsByClassName("test")
let setDivs = new Set(divs)
console.log(setDivs)
// 可以通過擴展運算符spread將集合轉換成數組
let array = [...set];
console.log(array)
let set1 = [...new Set(['a','b','c'])]
let set2 = [...new Set(['a','11','22'])]
//求set1、set2集合交集
let set3 = set1.filter(item => set2.indexOf(item) > -1)
console.log('set3', set3)
2.14 Map
ES6 提供了 Map 數據結構。它類似於對象,也是鍵值對的集合。但是“鍵” 的範圍不限於字符串,各種類型的值(包括對象)都可以當作鍵。Map 也實現了iterator 接口,所以可以使用『擴展運算符』和『for...of...』進行遍歷。map屬性和方法:
- size 返回Map集合個數
- get 根據鍵名獲取對應鍵值
- set 向Map中添加一個元素,返回當前的Map
- has 根據鍵名判斷當前Map中是否含有某個元素, 返回boolean值
- clear 清空Map中元素,返回undefined
//通過構造函數創建一個map對象,並且初始化
let map = new Map([
['name','張三'],
['age',18]
])
console.log(map)
//根據鍵名獲取對應的鍵值
console.log(map.get('name'))
//向map中添加一個元素
console.log(map.set('hoppy','football'))
//判斷map中是否含有某個元素,返回boolean
console.log(map.has('hoppy'))
//獲取map中元素個數
console.log(map.size)
//清空元素,返回undefine
console.log(map.clear())
//遍歷value
for (const item of map.values()) {
console.log(item)
}
// 遍歷key
for (const item of map.keys()) {
console.log(item)
}
2.15 class類
es6引入了 Class(類)這個概念,作爲對 象的模板。通過 class 關鍵字,可以定義類。基本上,ES6 的 class 可以看作只是 一個語法糖,它的絕大部分功能,ES5 都可以做到,新的 class 寫法只是讓對象 原型的寫法更加清晰、更像面向對象編程的語法而已。
- class 聲明類
- 通過constructor構造函數來初始化
- extends繼承父類
- super調用父類構造方法
- static定義靜態屬性和方法
- 父類方法可以重寫
class Person {
//靜態屬性
static hoppy = 'football'
//靜態方法
static read() {
console.log('read*****')
}
//構造函數初始化數據
constructor(name,age) {
this.name = name
this.age = age
}
//類中方法
sayHello() {
console.log(`${this.name}今年有${this.age},興趣愛好是:${Person.hoppy}`)
}
}
let per = new Person('張三',18)
//通過實例訪問屬性和方法
console.log(per.name)
per.sayHello()
//通過類名訪問靜態方法和屬性
Person.read()
console.log(Person.hoppy)
class Person {
static hoppy = 'football'
static read() {
console.log('read*****')
}
constructor(name,age) {
this.name = name
this.age = age
}
sayHello() {
console.log(`${this.name}今年有${this.age},興趣愛好是:${Person.hoppy}`)
}
}
class Student extends Person {
constructor(name,age,bj) {
super(name,age)
this.bj = bj
}
sayHello() {
console.log(`${this.name}今年有${this.age},班級是:${this.bj}`)
}
}
let per = new Student('張三',18,'三班')
per.sayHello()
console.log(per.name)
2.16 數值擴展
ES6 提供了二進制和八進制、16進制數值的新的寫法,分別用前綴 0b 和 0o 、0x表示。
let two = 0b1010
console.log(two) // 10
let eight = 0o777
console.log(eight) //511
let six = 0xfff
console.log(six) //4095
- Number.isFinite() 用來檢查一個數值是否爲有限
- Number.isNaN() 判斷當前數據的值是否爲NaN
- Number.parseInt() 將數據轉換成整型數據
- Number.parseFloat() 將數據轉換成浮點型數據
- Number.isInteger() 判斷當前數據的值是否爲整型
- Math.trunc() 去除小數部分,返回一個整數
console.log(Number.isFinite(1.333333333333)) // true
console.log(Number.isNaN(NaN)) //true
console.log(Number.parseInt(null)) //NaN
console.log(Number.parseInt(undefined)) //NaN
console.log(Number.parseInt('123')) //123
console.log(Number.parseInt('123.121')) //123
console.log(Number.parseInt('123.aaaa')) //123
console.log(Number.isInteger(123)) // true
console.log(Number.parseFloat(null)) //NaN
console.log(Number.parseFloat(1234)) //1234
console.log(Number.parseFloat('123.444aaa')) //123.444
console.log(Math.trunc(123.44)) //123
2.17 對象擴展
es6中對object對象新增一些方法
- Object.is() 比較兩個值是否嚴格相等,與`===`基本一致
- Object.assign() 對象合併,可以將原對象可枚舉所有屬性複製到目標對象
- __proto__、setPrototypeOf、 setPrototypeOf 可以直接設置對象的原型
let a = "123"
let b = "123"
console.log(Object.is(a,b)) // true
console.log(Object.is(NaN,NaN)) //true
console.log(NaN===NaN) //false
let obj1 = {a:'aa',b:'bb'}
let obj2 = {a:'a',c:'cc'}
// 返回目標對象的值,源對象的值會覆蓋目標對象同名的值
let obj3 = Object.assign(obj2,obj1) // {a:'aa',b:'bb',c:'cc'}
console.log(obj3)
console.log(obj2) // {a:'aa',b:'bb',c:'cc'}
2.17 模塊化
模塊化是將一個大的程序文件拆分成多個小文件,然後將這些小文件組合起來。優點:
- 代碼複用
- 高維護性
- 解決變量命名衝突
es6之前模塊化的產品:
-
CommonJS => NodeJS、Browserify
-
AMD => requireJS
-
CMD => seaJS
es6模塊的語法:
- export 命令用於規定模塊的對外接口
- import 命令用於輸入其他模塊提供的功能
//test1.js採用直接導出
export let name = '張三'
export function study() {
console.log('總結歸納自己學習的知識')
}
// test2.js採用通過一個對象全部導出
let name = "張三"
function study() {
console.log('總結歸納自己學習的知識')
}
export {name,study}
// test3.js採用默認導出
export default function() {
console.log('默認導出')
}
// 導入所有的模塊
import * as test1 from './test1.js'
// 採用解構賦值按需導入
import {name,study} from './test2.js'
// 默認導入
import defFunc from './test3.js'
console.log(test1.name)
test1.study()
console.log(name)
study()
defFunc()
三.ECMASript 7 新特性
3.1 Array.prototype.includes
includes方法用來檢測數組中是否含有某個元素,返回一個boolean的值
3.2 指數操作符
es7中引入指數運算符`**`,實現冪運算,功能與Math.pow()功能一樣
let array = ['a','b','c']
console.log(array.includes('a')) // true
console.log(2**4) //16
四.ECMASript 8 新特性
4.1 async/await
async/await配合使用,提供了一種異步編程解決方案。
async函數:
- async函數返回一個promise對象
- promise對象狀態有async函數返回值決定
await表達式:
- await必須寫在async函數中
- await右側表達式一般爲一個Promise對象
- await返回的是Promise成功的值
- await返回Promise失敗了,需要try catch把異常捕獲一下
<div>
<button onclick="asyc()">發送請求</button>
</div>
<script>
async function asyc() {
try {
let response = await requestData()
console.log(response)
} catch (error) {
console.log(error)
}
}
function requestData() {
return new Promise((resolve,reject) => {
//1.創建一個XMLHttpRequest對象
let xhr = new XMLHttpRequest()
//2.初始化
xhr.open('GET',"https://gank.io/api/v2/banners")
//3.綁定事件
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status===200) {
resolve(xhr.responseText)
}
}
//4.發送請求
xhr.send()
})
}
</script>
4.2 Object.values()和Object.entries()、Object.getOwnPropertyDescriptors()
- Object.values()方法返回一個給定對象的所有可枚舉屬性值的數組
- Object.entries()方法返回一個給定對象自身可遍歷屬性 [key,value] 的數組
- Object.getOwnPropertyDescriptors()方法返回指定對象自身所有屬性的描述對象
let obj = {a:'aa',b:'bb',c:'cc'}
let values = Object.values(obj);
console.log(values)
let entries = Object.entries(obj);
console.log(entries)
五.ECMASript 9 新特性
5.1. Rest/Spread 屬性
Rest 參數與 spread 擴展運算符在 ES6 中已經引入,不過 ES6 中只針對於數組, 在 ES9 中爲對象提供了像數組一樣的 rest 參數和擴展運算符。
//1.在對象上使用擴展運算符
function func1(obj) {
let {name,age,hoppy} = obj
console.log(name)
console.log(age)
console.log(hoppy)
}
let obj = {hoppy:'football'}
func1({name:'張三',age:18,...obj})
//2.在對象上使用rest參數
function func2({name,age,...obj}) {
console.log(name)
console.log(age)
//obj是一個對象類型
console.log(obj.hoppy)
}
func2({name:'李四',age:18,hoppy:'football'})
5.2. 正則表達式命名捕獲組
ES9 允許命名捕獲組使用符號`?<name>`,這樣獲取捕獲結果可讀性更強
let str = '<a href="http://www.baidu.com">百度</a>';
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result = reg.exec(str);
console.log(result.groups.url);
console.log(result.groups.text);
5.3. 正則表達式反向斷言
ES9 支持反向斷言,通過對匹配結果前面的內容進行判斷,對匹配進行篩選.
//聲明字符串
let str = 'js最牛逼123123哈哈哈哈4444耶'; //正向斷言
const reg = /\d+(?=耶)/;
const result = reg.exec(str);
//反向斷言
const reg = /(?<=逼)\d+/;
const result = reg.exec(str); console.log(result);
5.4. 正則表達式 dotAll 模式
正則表達式中點.匹配除回車外的任何單字符,標記`s`改變這種行爲,允許行終止符出現。
let str = ` <ul>
<li> <a>java</a>
<p>風靡天下</p> </li>
<li> <a>js/a>
<p>前端骨架</p> </li>
</ul>`;
//聲明正則
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
//執行匹配
const result = reg.exec(str);
let result;
let data = [];
while(result = reg.exec(str)){
data.push({title: result[1], time: result[2]}); }
//輸出結果
console.log(data);
六.ECMASript 10 新特性
- Object.fromEntries
- trimStart 和 trimEnd
- Array.prototype.flat 與 flatMap
- Symbol.prototype.description
//1.Object.fromEntries 將一個iterator轉換成對象
let map = new Map([['name','張三'],['a',111]])
map.set('age',18)
console.log(Object.fromEntries(map.entries()))
//2.trimStart和trimEnd去空格
let str = ' 我是張三 '
let aa = str.trimStart()
console.log(aa)
let bb = str.trimEnd()
console.log(bb)
console.log(str)
//3. flat可以平鋪多維數組
let array = [[1234,0977],[23123,4543]]
console.log(array.flat())
//4. flatMap可以重新組合新的數據
let array1 = ['a','b','c']
let result = array1.flatMap(item => {
return {item}
})
console.log(result)
七.ECMASript 11 新特性
- String.prototype.matchAll
- 類的私有屬性
- Promise.allSettled
- 可選鏈操作符
- 動態import 導入
- globalThis 對象
//1.String.prototype.matchAll
const regexp = RegExp('foo[a-z]*','g');
const str = 'table football, foosball';
const matches = str.matchAll(regexp);
for (const item of matches) {
console.log(item)
}
//2.類中私有屬性
class Person {
//類中私有屬性
#hoppy
constructor(name,age,hoppy) {
this.name = name
this.age = age
this.#hoppy=hoppy
}
sayHoppy() {
console.log(this.#hoppy)
}
}
let per = new Person('張三',18,'打籃球')
console.log(per.name)
// 直接訪問私有屬性返回undefine,私有屬性只能在Person類中訪問
console.log(per.hoppy)
per.sayHoppy()
//3.Promise.allSettle()與Promise.all()區別
//Promise.allSettled()無論成功與失敗都會將所有的結果返回,Promise.all()只有所有
//Promise成功,纔會將結果返回。否則只返回第一個錯誤的結果
let promise1 = new Promise((resolve,reject) => {
resolve('成功')
})
let promise2 = new Promise((resolve,reject) => {
resolve('失敗2')
})
let result = Promise.allSettled([promise1,promise2])
.then(value => {
console.log(value)
},err => {
console.log(err)
})
let result1 = Promise.all([promise1,promise2])
.then(value => {
console.log(value)
},err => {
console.log(err)
})
//4.可選操作符
let obj = {
name: '張三',
age: 18,
// hoppy: {
// one: 'football',
// two: 'basketball'
// }
}
function func(obj) {
console.log(obj?.hoppy?.one)
}
func(obj)
//5.import動態導入
function test() {
import('./test3.js')
.then(value => {
console.log(value.default)
},err => {
console.log(err)
})
}
test()