對前端開發中常使用的函式方法的一個小總結

已封號發表於2019-03-27
第一次在掘金髮文章,好緊張啊~~~~(>_<)~~~~
複製程式碼

對前端開發中常使用的函式方法的一個小總結
對前端開發中常使用的函式方法的一個小總結
對前端開發中常使用的函式方法的一個小總結

箭頭函式 MDN地址

先說一下箭頭函式,因為下面預設都使用箭頭函式,基本上不會出現function字樣。

// 僅做舉例使用哈

// 原始函式
function json2string(json){
  return JSON.stringify(json)
}

// 一級簡寫: 建立一個變數,並使這個變數等於一個箭頭函式
const json2string = (json) => {
  return JSON.stringify(json)
} 

// 二級簡寫:當函式只有一個引數的時候,可以省略引數括號
const json2string = json => {
  return JSON.stringify(json)
}

// 三級簡寫: 當函式表示式只有一行的時候,可以省略return和{}
const json2string = json => JSON.stringify(json)


// 感謝@blacker2018大佬提醒,本例的四級簡寫

const json2string = JSON.stringify


// 例外:當函式沒有引數的時候不能省略()
const helloWorld = () => 'hello world!'
複製程式碼

上面是箭頭函式的基本用法,另外說兩句:

​ 1, 箭頭函式沒有自己的this

​ 2, 箭頭函式的this指向從自身像外層找所能找到的第一個使用function宣告的函式(見例1)

​ 3, 如果一直找到最頂層都沒有function宣告的函式,this指向window

​ 3, 9021年了,多使用箭頭函式吧,畢竟好處那麼多,程式碼簡潔那麼多

例1:

export default {
  name: 'test',
  data(){ // 這裡不能用箭頭函式,會改變this指向,請注意
    return {
      count: 0
    }
  },
  mounted(){ // 同理,不能箭頭函式
    this.$axios({...}).then(res => this.count = res.count)
  }
}
複製程式碼

囉嗦一句,既然用了箭頭函式,就不要存 this 不然程式碼會讓後來人吐槽的

好了,BB了半天,正文開始了。

運算元組的一些常用方法

filter() MDN地址

filter的中文解釋是過濾,功能也顯而易見,在一個陣列中過濾出滿足要求的資料,並返回一個由所有滿足條件的資料組成的陣列

let arr = array.filter(callback[, thisObject]);

  • callback: 要對每個陣列元素執行的回撥函式。函式有三個引數:currentElement, currentIndex, currentArray
    • currentElement 當前元素
    • currentIndex 當前元素的下標 如用不到,可以省略
    • currentArray 當前元素所在的陣列(也就是當前被遍歷的陣列) 用不到可以省略
  • thisObject : 在執行回撥函式時定義的this物件。

e.g.1 找出一個陣列中所有大於3的數字

let arr = [1,2,3,4,5,6,7,8,9]
let arr2 = arr.filter(ele => ele > 3)
複製程式碼

e.g.2 過濾資料資料中的所有disabledtrue的資料

const data = [
  {
    title: 'test1',
    disabled: false,
  },
  /*...省略100個*/
  {
    title: 'test100',
    disabled: true,
  }
]
const disabledList = data.filter(ele => ele.disabled)
複製程式碼

e.g.3 這個很重要,還是上面的資料,需求要實現找出所有disabledtrue的資料的title

const disabledList = data.filter(ele => ele.disabled && ele.title) // 這樣可以嗎? false. 因為filter 不會執行 第一個條件之後的所有條件
複製程式碼

難道這個需求就不能實現了嗎?非也。接著往下看

map() MDN地址

這裡的map不是“地圖”的意思,而是指“對映”。map函式類似於上面的filter一樣,接收一個函式,對陣列中的每個元素執行相同的操作,接收一個並返回一個由所有滿足條件的資料組成的陣列

let newArray = array.map(callback[, thisObject]);

  • callback: 要對每個陣列元素執行的回撥函式。函式有三個引數:currentElement, currentIndex, currentArray callback函式如果不寫return 預設return undefined
    • currentElement 當前元素
    • currentIndex 當前元素的下標 如用不到,可以省略
    • currentArray 當前元素所在的陣列(也就是當前被遍歷的陣列) 用不到可以省略
  • thisObject : 在執行回撥函式時定義的this物件。

e.g.1 上面filter不能實現的功能,現在配合map實現以下

const data = [
  {
    title: 'test1',
    disabled: false,
  },
  /*...省略100個*/
  {
    title: 'test100',
    disabled: true,
  }
]
// map 函式 當條件不滿足時會return undefined 再filter過濾一下
const disabledList = data.map(ele => ele.disabled && ele.title).filter(ele => ele) 
複製程式碼

e.g.2

組合資料,這個例子主要是描述一種業務場景,可以看到data中的product欄位從個人理解的意義上講,price應該和title && author是一個級別的。現在我們就實現我們的想法

const data = [
  {
    title: 'egg',
    author: 'chicken',
    product: {
      price: 100,
      age: 2
    }
  },
  {
    title: 'dog',
    author: 'dog',
    product: {
      price: 1000,
      age: 0.5
    }
  }
]

const newArray = data.map(ele => {
  return {
    ...ele,
    ...ele.product || {} // 相容沒有product情況
  }
})

// 上面的函式得到的結果就滿足了我們自身的需求 ...擴充套件運算子後面會講
{
    title: 'egg',
    author: 'chicken',
    price: 100,
    age: 2
    product: {
	  price: 100,
      age: 2
    }
  }
複製程式碼

forEach() MDN地址

forEach函式類似於上面的map一樣,接收一個函式,對陣列中的每個元素執行相同的操作,和filter/map不同的是 forEach 沒有返回值 forEach()對於空陣列是不會執行回撥函式的

array.forEach(callback[, thisObject]);

  • callback: 要對每個陣列元素執行的回撥函式。函式有三個引數:currentElement, currentIndex, currentArray
    • currentElement 當前元素
    • currentIndex 當前元素的下標 如用不到,可以省略
    • currentArray 當前元素所在的陣列(也就是當前被遍歷的陣列) 用不到可以省略
  • thisObject : 在執行回撥函式時定義的this物件。
const data = [
  {
    title: 'test1',
    disabled: false,
  },
  /*...省略100個*/
  {
    title: 'test100',
    disabled: true,
  }
]
// map 函式 當條件不滿足時會return undefined 再filter過濾一下
const disabledList = data.map(ele => ele.disabled && ele.title).filter(ele => ele) 


/***************************************************/
// 上面的例子使用了filter和map兩個遍歷 使用forEach一遍就可以實現 更高效

let arr = []
data.forEach(ele =>{
  if(ele.disabled) arr.push(ele.title)
})
複製程式碼

some() MDN地址

some中文意思是一些,在JS中表示陣列中當有一個資料滿足條件時返回true

some()是對陣列中每一項執行給定函式,如果該函式對任一項返回true,則返回true。

some接收一個函式作為引數,函式有三個引數:

  • current 當前元素
  • index 當前下標
  • array 被迴圈的陣列

e.g.1

const data = [1,2,3,4,5,6,8]
console.log(data.some(ele => ele > 4)) // true
console.log(data.some(ele => ele < 4)) // true
console.log(data.some(ele => ele > 8)) // false
console.log(data.some(ele => ele >= 2)) // true
console.log(data.some(ele => ele < 1)) // false
複製程式碼

e.g.2

const data = [
  { id: 2, count: 200 },
  { id: 4, count: 300 },
  { id: 6, count: 100 },
  { id: 8, count: 700 }, 
]
console.log(data.some(ele => ele.count > 700)) // false
console.log(data.some(ele => ele.count > 600)) // true
複製程式碼

every() MDN地址

every()是對陣列中每一項執行給定函式,如果該函式對每一項返回true, 則返回true。

every接收一個函式作為引數,函式有三個引數:

  • current 當前元素
  • index 當前下標
  • array 被迴圈的陣列
const data = [
  { id: 2, count: 200 },
  { id: 4, count: 300 },
  { id: 6, count: 100 },
  { id: 8, count: 700 }, 
]
console.log(data.every(ele => ele.count > 700)) // false
console.log(data.every(ele => ele.count < 900)) // true
複製程式碼

reduce() MDN地址

arr.reduce(callback,[initialValue])
複製程式碼
  • callback (執行陣列中每個值的函式,包含四個引數)
    • previousValue (上一次呼叫回撥返回的值,或者是提供的初始值(initialValue))
    • currentValue (陣列中當前被處理的元素)
    • index (當前元素在陣列中的索引)
    • array (呼叫 reduce 的陣列)
  • initialValue (作為第一次呼叫 callback 的第一個引數。)
// 經典面試題: 使用reduce同時實現map和filter
// 例子: 找出所有double後大於50的數
const doubledOver50 = num => num.reduce((finalList, ele) => {
  const number = ele * 2
  if (number > 50) {
    finalList.push(ele)
  }
  return finalList
}, [])
doubledOver50(numbers) // [30, 40]
複製程式碼

** reduce還有很多妙用,可以掘金搜一下哈

flat() MDN地址

這個是ES10的方法,實現陣列扁平化,flat函式接收一個值指定要提取巢狀陣列的結構深度,預設值為 1,返回一個包含將陣列與子陣列中所有元素的新陣列。

由於是ES10的方法,使用的話需要考慮一下相容性問題,貼上MDN地址:Array.prototype.flat()

let arr1 = [1, 2, [3, 4]];
arr1.flat();  // [1, 2, 3, 4]

let arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(); // [1, 2, 3, 4, [5, 6]]

let arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); // [1, 2, 3, 4, 5, 6]

//使用 Infinity 作為深度,展開任意深度的巢狀陣列
arr3.flat(Infinity); // [1, 2, 3, 4, 5, 6]
複製程式碼

扁平化與空項

flat() 方法會移除陣列中的空項:

let arr4 = [1, 2, , 4, 5];
arr4.flat(); // [1, 2, 4, 5]
複製程式碼

indexOf() MDN地址

indexOf()接收一個引數,並查詢該元素在陣列中的下標,遍歷方向是從前向後遍歷

let arr = [1,2,3,4,5,6,7]

const index = arr.indexOf(2) // 1
複製程式碼

lastIndexOf() MDN地址

lastIndexOf()接收一個引數,並查詢該元素在陣列中的下標, 與indexOf不同的是遍歷方向是從後向前遍歷

let arr = [1,2,3,4,5,2,7]
const index = arr.lastIndexOf(2) // 5
複製程式碼

find() MDN地址

find()找到陣列中第一個符合條件的資料

find()接收一個函式作為引數, 函式的可選引數有

  • currentValue
  • index
  • arr

e.g.1:

let students = [
  { name: 'tom', age: 18 },
  { name: 'jeck', age: 20 },
  { name: 'bob', age: 19 }
]

let monitor = students.find(ele => ele.age > 18) // {name: 'jeck', age: 20}   [返回第一個符合條件的資料並結束迴圈]
複製程式碼

findIndex() MDN地址

查詢第一個符合條件的元素的下標,和find的區別就是find返回元素, findIndex返回下標

array.findIndex(callback, thisValue)
複製程式碼
  • callback: 要對每個陣列元素執行的回撥函式。函式有三個引數:currentElement, currentIndex, currentArray
    • currentElement 當前元素
    • currentIndex 當前元素的下標 如用不到,可以省略
    • currentArray 當前元素所在的陣列(也就是當前被遍歷的陣列) 用不到可以省略
  • thisValue : 在執行回撥函式時定義的this物件。
let students = [
  { name: 'tom', age: 18 },
  { name: 'jeck', age: 20 },
  { name: 'bob', age: 19 }
]

let monitor = students.findIndex(ele => ele.age > 18) // 1 [返回第一個符合條件的資料的下標並結束迴圈]
複製程式碼

操作物件的一些常用方法

Object.assign() MDN地址

Object.assign() 方法用於將所有可列舉屬性的值從一個或多個源物件複製到目標物件。它將返回目標物件。

工作中用的最多的就是合併兩個物件了,但是大多數情況下可以使用擴充套件運算子代替

對於Object.assign()是否能實現深拷貝,答案是否。具體原因點我

下面的例子僅僅只是介紹一下物件合併

let obj1 = { a: 1 }
let obj2 = { b:2 }
let obj3 = Object.assign(obj1, obj2) // {a: 1, b: 2}
let obj4 = Object.assign({}, obj1, obj2, obj3) // {a: 1, b: 2}

// 注意:物件的合併是從右向左進行,在上面的例子中,如果obj2中有和obj3一樣的key 那麼obj2中key對應的val會被obj3中對應的val覆蓋掉
複製程式碼

Object.keys() MDN地址

Object.keys() 方法會返回一個由一個給定物件的自身可列舉屬性組成的陣列,陣列中屬性名的排列順序和使用 for...in 迴圈遍歷該物件時返回的順序一致 。

//  陣列
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// 類陣列物件
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// 隨機鍵排序的類陣列物件
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']


複製程式碼

通常使用Object.keys()代替for...in來遍歷物件

let obj = {
  a: 1,
  b: 2
}
let keys = Object.keys(obj).map(ele => ele += 'aaaaa' /* 可以分別對每個key做一些改造 */)

複製程式碼

Object.values() MDN地址

Object.values()方法返回一個給定物件自身的所有可列舉屬性值的陣列,值的順序與使用for...in迴圈的順序相同 ( 區別在於 for-in 迴圈列舉原型鏈中的屬性 )。

var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// 類陣列物件
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']

// 隨機鍵排序的類陣列物件
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']
複製程式碼

通常使用Object.values()代替for...in來遍歷物件取value

let obj = {
  a: 1,
  b: 2
}
let values = Object.values(obj).map(ele => ele++ /* 可以分別對每個value做一些改造 */)


複製程式碼

擴充套件運算子(…) MDN地址

在開發工作中,很多場景下都可以使用簡化程式碼,下面列了一些使用場景

  • Math.max (求陣列最大值)

    // e.g.1 求陣列最大值
    let data = [1,2,3,4,5,6,7,8]
    const big = Math.max(...data) // 8
    
    // e.g.2 取庫存量最多商品的庫存
    let data = [
      {
        name: '橘子',
        stock: 100
      },
      {
        name: '橙子',
        stock: 300
      },
      {
        name: '蘋果',
        stock: 700
      }
    ]
    
    // 結合map使用(map返回一個新陣列)
    const big = Math.max(...data.map(ele => ele.stock)) // 700
    // (其實這個例子用sort方法就能實現,只是舉個例子)
    
    複製程式碼
  • Math.min

    // e.g.1 取最小值
    // e.g.1 求陣列最大值
    let data = [1,2,3,4,5,6,7,8]
    const big = Math.min(...data) // 1
    
    複製程式碼
  • Array.from

    // e.g.1 陣列去重
    let data = [1,1,2,3,4,4,5,6]
    const arr = [...new Set(data)] // [1,2,3,4,5,6]
    
    複製程式碼
  • 字串轉陣列

    // e.g.1 將一個字串轉成陣列
    const arr = [...'hello'] // [‘h’, 'e', 'l', 'l', 'o']
    
    複製程式碼
  • 合併陣列

    // e.g.1 合併兩個陣列
    let arr1 = [1,2,3,4,5,6]
    let arr2 = [1,2,3,4,5,6]
    let arr2 = [...arr1, ...arr2] // [1,2,3,4,5,6,1,2,3,4,5,6]
    
    複製程式碼
  • 合併物件

    let data1 = {
      name: '王二麻子',
      age: 12,
      class: '2(1)班'
    }
    let data2 = {
      name: '王二麻子',
      hobby: '王者榮耀'
    }
    
    let w2mz = {...data1, ...data2} 
    // 輸出:
    {
      name: '王二麻子',
      age: 12,
      class: '2(1)班',
    	hobby: '王者榮耀'
    }
    
    // ** 注意: 當出現重複的key的時候,後面的key對應的val會覆蓋掉前面的key對應的val
    複製程式碼
  • 充當函式省略引數 …other

    …other 在函式體內使用other的時候, other是一個由省略引數組成陣列 e.g.1

const sum = (a, b, ...num) => {
    let total = num.reduce((prev, current) => current + prev, 0) 
    return a + b + total
}
sum(1, 2, 3, 4, 5, 6, 7, 8, 9)
複製程式碼

e.g.2

// 實現一個累加器 要求 可以傳任意個引數 函式返回一個所有引數的累加和
const sum = (...num) => num.reduce((prev, current) => current + prev, 0) 
console.log(sum(1, 2, 3, 4)) // 10
複製程式碼

總結

有錯別字或者理解有誤的地方大佬們指出來哈。千萬不要: he~ tui(我可以發語音?)

對前端開發中常使用的函式方法的一個小總結

相關文章