重學ES6之出來混早晚要還的(四)

本系列博客爲ES6基礎語法的使用及總結,若有錯誤,歡迎指正。
重學ES6之出來混早晚要還的(四)主要包括Array.from()Array.of()find()/findIndex()some()/every()PromiseSymbol()面試

其餘筆記:
重學ES6之出來混早晚要還的(一)
重學ES6之出來混早晚要還的(二)
重學ES6之出來混早晚要還的(三)
重學ES6之出來混早晚要還的(五)
重學ES6之出來混早晚要還的(六)
數據類型的轉換/判斷/比較編程

Array.from()/Array.of()

這兩個方法不是原型上面的方法,直接使用會報錯segmentfault

let arr = [1,2,3];
console.log(arr.from());
//Uncaught TypeError: arr.from is not a function

console.log(arr.of()); 
//Uncaught TypeError: arr.of is not a function

Array.from()

1.用法
用於把一個類數組對象或者是一個可遍歷對象轉換爲一個真正的數組數組

類數組對象是啥?
具備索引屬性(數字),有length屬性的對象;好比NodeList對象
可遍歷對象是啥?
別問,問就是讓你去看前面兩篇筆記

(1) 格式:
Array.from(arrayLike[, mapFn[, thisArg]])
(2) 參數:promise

  • arrayLike 想要轉換成數組的僞數組對象或可迭代對象。
  • mapFn 可選 若是指定了該參數,新數組中的每一個元素會執行該回調函數。
  • thisArg 可選 執行回調函數 mapFn 時 this 對象。

(3) 返回值:一個新的數組實例。
(4) 示例app

// 從String生成數組
Array.from('foo'); 
// [ "f", "o", "o" ]

console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]

Array.from(obj, mapFn, thisArg)的格式至關於 Array.from(obj).map(mapFn, thisArg)異步

let oLis = document.querySelectorAll('li');
let num = Array.from(oLis).map(li => li.innerHTML);
console.log(num); //["1", "2", "3"]
//等價於
let liArr = Array.from(oLis,li => li.innerHTML);
console.log(liArr); //["1", "2", "3"]

2.應用場景異步編程

image.png

  • 將字符串轉爲字符串數組測試

    let arr = Array.from('ridiculous');
    console.log(arr);  //["r", "i", "d", "i", "c", "u", "l", "o", "u", "s"]
    
    let str = 'ridiculous';
    let arr2 = str.split('');
    console.log(arr2); //["r", "i", "d", "i", "c", "u", "l", "o", "u", "s"]

Array.of()

1.用法
Array.of()方法建立一個具備可變數量參數的新數組實例,而不考慮參數的數量或類型。

 Array.of() 和 Array 構造函數之間的區別在於處理整數參數:
Array.of(7)建立一個具備單個元素爲7的數組(注意:數組的長度是1),
Array(7) 建立一個長度爲7的空數組(注意:這是指一個有7個空位(empty)的數組,而不是由7個undefined組成的數組)。

let arr = Array(5);
console.log(arr); //[empty × 5] 是一個長度爲5,數值都爲空的數組
let arr2 = Array.of(5);
console.log(arr2); //[5] 是一個長度爲1,元素值爲5的數組

let arr = Array(0);
console.log(arr); //[]
let arr2 = Array.of(0);
console.log(arr2); //[0]

也就是說使用 Array.of() 可以保證傳入的數據和返回結果的一致性,無論傳入多少個參數,返回的是由這些元素組成的數組;彌補了Array()構造函數的不足

let arr = Array(1,2,3);
console.log(arr); //[1,2,3]

let arr2 = Array.of(1,2,3);
console.log(arr2); //[1,2,3]

find()/findIndex()/some()/every()

find()

find() 方法返回數組中知足提供的測試函數的第一個元素的值。不然返回 undefined。

找到知足條件的第一個就會當即中止

1.用法
格式:arr.find(callback[, thisArg])
參數:① callback 在數組每一項上執行的函數,接收 3 個參數:

  • element 當前遍歷到的元素。
  • index 可選 當前遍歷到的索引。
  • array 可選 數組自己。

② thisArg 可選 執行回調時用做this 的對象。

返回值:數組中第一個知足所提供測試函數的元素的值,都找不到不然返回 undefined。

let inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

let cherry = inventory.find(fruit => fruit.name === 'cherries');
console.log(cherry); // { name: 'cherries', quantity: 5 }

findIndex()

findIndex()方法返回數組中知足提供的測試函數的第一個元素的索引。找不到則返回-1。
1.用法
格式:arr.findIndex(callback[, thisArg])
參數:① callback 針對數組中的每一個元素, 都會執行該回調函數, 執行時會自動傳入下面三個參數:

  • element 當前元素。
  • index 當前元素的索引。
  • array 調用findIndex的數組。

② thisArg 可選。執行callback時做爲this對象的值.
返回值:數組中經過提供測試函數的第一個元素的索引。不然,返回-1

let cherryIndex = inventory.findIndex(fruit => fruit.name === 'cherries');
console.log(cherryIndex); //2

some()

some() 方法測試數組中是否是至少有1個元素經過了被提供的函數測試。它返回的是一個Boolean類型的值。

找到知足條件的第一個就會當即中止

1.用法
格式:arr.some(callback(element[, index[, array]])[, thisArg])
參數: ① callback用來測試每一個元素的函數,接受三個參數:

  • element 數組中正在處理的元素。
  • index 可選 數組中正在處理的元素的索引值。
  • array 可選 some()被調用的數組。

② thisArg可選
執行 callback 時使用的 this 值。
返回值:數組中有至少一個元素經過回調函數的測試就會返回true;全部元素都沒有經過回調函數的測試返回值纔會爲false。

let isZero = inventory.some(fruit => fruit.quantity === 0);
console.log(isZero); //true

every()

every() 方法測試一個數組內的全部元素是否都能經過某個指定函數的測試。它返回一個布爾值。

若是有一個爲false,則當即返回false,後面的再也不執行

1.用法
格式:arr.every(callback[, thisArg])
參數:① callback 用來測試每一個元素的函數,它能夠接收三個參數:

  • element 用於測試的當前值。
  • index 可選 用於測試的當前值的索引。
  • array 可選 調用 every 的當前數組。

② thisArg 執行 callback時使用的 this 值。
返回值:若是回調函數的每一次返回都爲 truthy 值,返回 true ,不然返回 false。

let allZero = inventory.every(fruits => fruits.quantity === 0);
console.log(allZero); //false

Promise

官方說法之又臭又長不看版:

Promise 對象用於表示一個異步操做的最終完成 (或失敗), 及其結果值.

Promise構造函數執行時當即調用executor函數, resolve 和 reject 兩個函數做爲參數傳遞給executor(executor 函數在Promise構造函數返回所建promise實例對象前被調用)。resolve 和 reject 函數被調用時,分別將promise的狀態改成fulfilled(完成)或rejected(失敗)。executor 內部一般會執行一些異步操做,一旦異步操做執行完畢(可能成功/失敗),要麼調用resolve函數來將promise狀態改爲fulfilled,要麼調用reject 函數將promise的狀態改成rejected。若是在executor函數中拋出一個錯誤,那麼該promise 狀態爲rejected。executor函數的返回值被忽略。

1.Promise基本概念

1.1 what
promise是ES6中新增的異步編程解決方案。簡單說就是一個容器,裏面保存着某個將來纔會結束的事件的結果。
從語法上說,Promise 是一個對象,從它能夠獲取異步操做的消息。能夠經過new Promise(function(resolve, reject) {})來建立

1.2 why
經過Promise就能夠實現:用同步的流程來表示異步的操做;解決回調順序的不肯定性,解決回調地獄的問題

1.3 how
Promise構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolvereject。它們是兩個函數,由JavaScript引擎提供,不用本身部署。

resolve函數的做用是,將Promise對象的狀態從「未完成」變爲「成功」(即從Pending變爲Resolved),在異步操做成功時調用,並將異步操做的結果,做爲參數傳遞出去;

reject函數的做用是,將Promise對象的狀態從「未完成」變爲「失敗」(即從Pending變爲Rejected),在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去。

let p = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 異步操做成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

2.Promise對象三種狀態(面試必問)

  • pending:默認狀態,只要沒有說明promise任務是成功仍是失敗就是pending狀態
  • fulfilled(resolved):只要調用resolve函數, 狀態就會變爲fulfilled, 表示操做成功
  • rejected:只要調用rejected函數, 狀態就會變爲rejected, 表示操做失敗

3.Promise 對象的特色

3.1 對象的狀態不受外界影響,只有異步操做的操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。

3.2 一旦狀態改變,就不會再改變,任什麼時候候均可以獲得這個結果。
Promise 對象的狀態改變,只有兩種可能:從Pending變爲Resolved;從Pending變爲Rejected

4.Promise 經常使用的方法有哪些?它們的做用是什麼?

4.1 Promise.then()

  • Promise 實例具備then方法,也就是說,then方法是定義在原型對象Promise.prototype上的。
  • 它的做用是爲 Promise 實例添加狀態改變時的回調函數。
  • then方法的第一個參數是resolved狀態的回調函數,第二個參數(可選)是rejected狀態的回調函數。

4.2 Promise.catch()
Promise.catch方法是.then(null, rejection).then(undefined, rejection)的語法糖,用於指定發生錯誤時的回調函數。

4.3 Promise.all()
all方法接收一個數組,,當全部實例promise的結果都是成功時,纔會執行後面then方法裏面的內容
若是有一個promise實例的狀態是失敗的,那麼就會執行catch方法

const userPromise = new Promise((resolve,reject) =>{
  setTimeout(() => {
      resolve(['lucy','lily','eli']);
  },2000)
});

const moviePromise = new Promise((resolve,reject) => {
  setTimeout(() => {
      // resolve({name: '卡薩布蘭卡',score: '9.8', published: '1964'});
      reject('no movie found');
  },500);
});
Promise.all([userPromise,moviePromise])
      .then(response => {
          console.log(response);
          let [user,movie] = response;
          console.log(user);
          console.log(movie);
      })
      .catch(err => console.log(err));

已知userPromise的狀態已經肯定了是成功的,因此all方法返回的內容取決於moviePromise的狀態:
若是moviePromise的狀態是成功,則all方法執行then裏面的內容。正常打印response、user、movie
若是moviePromise的狀態是失敗,則all方法執行catch裏面的內容。拋出錯誤

4.4 Promise.race()
race方法由數組裏面第一個promise實例返回的狀態決定,若是第一個promise返回的狀態是成功,那麼race方法執行then方法裏面的內容;
若是第一個promise實例返回的狀態是失敗,則race方法執行catch方法裏面的內容

const userPromise = new Promise((resolve,reject) =>{
  setTimeout(() => {
      resolve(['lucy','lily','eli']);
  },2000)
});

const moviePromise = new Promise((resolve,reject) => {
  setTimeout(() => {
      resolve({name: '卡薩布蘭卡',score: '9.8', published: '1964'});
      // reject(Error('no movie found'));
  },500);
});
Promise.race([userPromise,moviePromise])
        .then(response => {
            console.log(response);
        })
        .catch(err => console.log(err));

race方法執行的結果取決於先執行的moviePromise返回的結果,
若是moviePromise的狀態是成功的,那麼race方法執行then裏面的內容。正常打印response
若是moviePromise的狀態是失敗的,那麼race方法執行執行catch裏面的內容。拋出錯誤

5.Promise常見面試題

5.1

let promise = new Promise((resolve, reject)=>{
  console.log('我是promise任務');
  resolve('resolved')
})
promise.then(res =>{
  console.log(res)
})
console.log("我是同步任務");
  setTimeout(()=>{
  console.log("我是延時任務");
}, 0)

答案:執行順序:我是promise任務、我是同步任務、resolved、我是延時任務。
5.2

console.log(1);
setTimeout(()=>{
  console.log(2);
});
setTimeout(()=>{
  console.log(3);
});
const promise = new Promise((resolve) => {
  console.log(4);
  resolve();
});
promise.then(()=>{
  console.log(5);
});
console.log(6); //1 4 6 5 2 3

Symbol

symbol 是一種基本數據類型 (primitive data type)。
Symbol()函數會返回symbol類型的值
每一個從Symbol()返回的symbol值都是惟一的。一個symbol值能做爲對象屬性的標識符。

1.什麼Symbol?

  • Symbol是ES6中新增的一種數據類型,被劃分到了基本數據類型中
  • Symbol的做用:用來表示一個獨一無二的值
  • Symbol的意義:用來解決對象中屬性命名的衝突問題

2.如何生成一個Symbol

2.1 採用let xxx = Symbol();便可建立一個獨一無二的值;利用typeof 檢查這個獨一無二的值時,返回symbol(小寫s)

每一次建立的Symbol不和其餘Symbol相等(獨一無二)

const peter = Symbol();
console.log(peter); //Symbol()
console.log(typeof peter); //symbol

const student = Symbol();
console.log(student === peter); //false

2.2 能夠在括號裏面爲每個Symbol添加描述,用於區分Symbol

經過Symbol生成獨一無二值時傳入的字符串僅僅是一個標記, 方便咱們閱讀代碼, 沒有其它任何意義

const peter = Symbol('peter');
console.log(peter); //Symbol(peter)

const student = Symbol('student');
console.log(student); //Symbol(student)

3.注意點

3.1 經過Symbol生成獨一無二值時須要在後面加上(), 可是前面不能加new, 由於它不是引用類型

3.2 作類型轉換的時候不能轉換成數值類型,且不能作任何運算

let n = Symbol("name");
console.log(String(n));//字符串Symbol(name)
console.log(Boolean(n));//true
console.log(Number(n));//報錯 Uncaught TypeError: Cannot convert a Symbol value to a number

3.3 對象的屬性名是Symbol類型的話,是不可遍歷的

不能用for inObject.keys()Object.getOwnPropertyNames()遍歷

const list = {
   [Symbol('Ann')]: {score: 99, gender: 'female'},
   [Symbol('Bob')]: {score: 99, gender: 'male'},
   [Symbol('Eli')]: {score: 99, gender: 'male'},
 };

 for(let key in list){
   console.log(key); //什麼也沒輸出
   console.log(list[key]); //什麼也沒輸出
 }

let res = Object.keys(list);
console.log(res); //[]

let res2 = Object.getOwnPropertyNames(list);
console.log(res2); //[]

3.4 Object.getOwnPropertySymbols()方法遍歷屬性時返回一個symbol類型的數組。

let res3 = Object.getOwnPropertySymbols(list);
console.log(res3);

3.5 若是想使用Symbol變量做爲對象屬性的名稱, 那麼必須使用對象名稱[],獲取的時候也只能用[]的方式

const list = {
   [Symbol('Ann')]: {score: 99, gender: 'female'},
   [Symbol('Bob')]: {score: 99, gender: 'male'},
   [Symbol('Eli')]: {score: 99, gender: 'male'},
};

const name = Symbol('Eli');
const say = Symbol('say');
const person = {
    [name] : 'ghk',
    [say]: function () {
         console.log('say');
    }
}
//獲取屬性的時候
console.log(person[name]);
console.log(person[say]);
相關文章
相關標籤/搜索