JavaScript 數組、字符串、Map、Set 方法整理


在線閱讀

https://www.kancloud.cn/chenmk/web-knowledges/1080519

數組

  • isArray():Array.isArray(value) 用於檢測變量是否為數組類型
  • toString():把數組轉換為字符串,並返回結果,每一項以逗號分隔
  • push() & pop():push() 方法用於數組末尾添加項,pop() 方法彈出數組末尾項並返回該項
  • shift() & unshift():移除數組中的第一個項並返回該項 / 數組最前端添加項
  • reverse():反轉數組順序,會改變原數組並返回反轉后的數組
  • sort():排序數組,默認為升序;可接受一個自定義的比較函數作為參數
  • concat():基於當前數組的所有項創建一個新數組,該方法會先創建一個當前數組的副本,然后將接收到的參數添加到這個副本的末尾,最后返回新構建的數組
  • slice():基於當前數組中的一或多個項創建一個新數組
  • splice():刪除數組中的項或往數組中插入項
  • indexOf() & lastIndexOf():接收兩個參數,要查找的項和可選的表示查找起點位置的索引
  • 迭代方法:迭代方法都不會修改原數組。每個方法都接收兩個參數:要在每一項上運行的函數和 (可選的)運行該函數的作用域對象——影響 this 的值。傳入這些方法中的函數會接收三個參數:數組項的值、該項在數組中的位置和數組對象本身。
    • every():對數組中的每一項運行給定函數,如果該函數對每一項都返回 true,則返回 true
    • some():對數組中的每一項運行給定函數,如果該函數對任一項返回 true,則返回 true
    • filter():對數組中的每一項運行給定函數,返回該函數會返回 true 的項組成的數組
    • forEach():對數組中的每一項運行給定函數。這個方法沒有返回值
    • map():對數組中的每一項運行給定函數,返回每次函數調用的結果組成的數組
  • reduce & reduceRight():歸並方法,迭代數組的所有項,然后得到一個最終返回的值
  • join(seperator):把數組中的所有元素放入一個字符串。元素是通過指定的分隔符進行分隔的。seperator 是可選參數,默認使用','分隔

下面通過一些示例來加深對一些稍微復雜的函數的理解:
1.sort()
values.sort(compare),比較函數(compare)接收兩個參數,如果第一個參數應該位於第二個之前則返回一個負數,如果兩個參數相等則返回 0,如果第一個參數應該位於第二個之后則返回一個正數

function compare (value1, value2) {
    if(value1 < value2){
        return -1
    } else if (value1 > value2) {
        return 1
    } else {
        return 0
    }
}

對於數值類型或者其 valueOf() 方法會返回數值類型的對象類型,可以使用一個更簡單的比較函數。這個函數只要用第二個值減第一個值即可

function compare (value1, value2) { return value2 - value1 }

由於比較函數通過返回一個小於零、等於零或大於零的值來影響排序結果,因此減法操作就可以適當地處理所有這些情況
2.concat() 與 slice() 與 splice()
在沒有給 concat()方法傳遞參數的情況下,它只是復制當前數組並返回副本。如果傳遞給 concat() 方法的是一或多個數組,則該方法會將這些數組中的每一項都添加到結果數組中。如果傳遞的值不是數組,這些值就會被簡單地添加到結果數組的末尾。

var colors = ["red", "green", "blue"]
var colors2 = colors.concat("yellow", ["black", "brown"])
alert(colors) // red,green,blue 
alert(colors2) // red,green,blue,yellow,black,brown

slice()方法可以接受一或兩個參數,即要返回項的起始和結束位置。在只有一個參數的情況下,slice() 方法返回從該參數指定位置開始到當前數組末尾的所有項。如果有兩個參數,該方法返回起始和結束位置之間的項,但不包括結束位置的項。注意,slice() 方法不會影響原始數組。

var colors = ["red", "green", "blue", "yellow", "purple"]
var colors2 = colors.slice(1)
var colors3 = colors.slice(1,4)
alert(colors2) // green,blue,yellow,purple
alert(colors3) // green,blue,yellow

splice()

  • 刪除:可以刪除任意數量的項,只需指定 2 個參數:要刪除的第一項的位置和要刪除的項數。例如,splice(0,2)會刪除數組中的前兩項。
  • 插入:可以向指定位置插入任意數量的項,只需提供 3 個參數:起始位置、0(要刪除的項數)和要插入的項。如果要插入多個項,可以再傳入第四、第五,以至任意多個項。例如splice(2,0,"red","green")會從當前數組的位置 2 開始插入字符串"red"和"green"。
  • 替換:可以向指定位置插入任意數量的項,且同時刪除任意數量的項,只需指定 3 個參數:起始位置、要刪除的項數和要插入的任意數量的項。插入的項數不必與刪除的項數相等。例如, splice (2,1,"red","green")會刪除當前數組位置 2 的項,然后再從位置 2 開始插入字符串 "red" 和 "green"。(先刪除再插入)
  • 返回值:splice() 方法始終都會返回一個數組,該數組中包含從原始數組中刪除的項(如果沒有刪除任何項,則返回一個空數組)

3.迭代方法的使用

var numbers = [1,2,3,4,5,4,3,2,1]
var filterResult = numbers.filter(function (item, index, array) {
 return (item > 2)
})
alert(filterResult) // [3,4,5,4,3]

來看一道常見的面試題:['1', '2', '3'].map(parseInt)答案是多少
答案 :[1, NaN, NaN]
解析:parseInt 接收兩個參數 (sting, radix),其中 radix 代表進制。省略 radix 或 radix = 0,則數字將以十進制解析
因此,map 遍歷 ['1', '2', '3'],相應 parseInt 接收參數如下
parseInt('1', 0)  // 1
parseInt('2', 1) // NaN
parseInt('3', 2)  // NaN
通過下面一些示例你可以更清晰地理解 parseInt() 方法:

parseInt("10")		    //返回 10
parseInt("19",10)		//返回 19 (10+9)
parseInt("11",2)		//返回 3 (2+1)
parseInt("17",8)		//返回 15 (8+7)
parseInt("1f",16)		//返回 31 (16+15)

4.歸並方法的使用

reduce(function (prev, curr, index, arr) {}, optional)
  • 參數依次為:前一個值,當前值,項的索引,數組對象。
  • 函數返回的任何值都會作為第一個參數自動傳給下一項,首次執行時 prev 就是數組第一個元素,curr 是數組的第二個元素。
  • 還可以接受一個參數作為歸並的初始值,如果傳入了這個參數,首次執行的 prev 就是這個值,curr 是數組的第一個元素

通過這個常見面試題可以加深我們對 reduce 的理解:用數組的 reduce 實現 map 方法

// map(function (item, index, arr) {}) 
// 對數組的每個元素執行相應的操作,返回一個新數組,其由由操作后的元素組成;不會修改原數組

Array.prototype.map = function (callback) {
  let arr = this // this->調用該方法的數組
  return arr.reduce((prev, curr, index, arr ) => {
    prev.push(callback(curr, index, arr)) // 數組中每一項執行傳入的回調函數
    return prev
  }, []) // 最后返回的是prev,傳入[]則第一輪prev = [], curr= 數組第1個元素
}

let m = [1, 2, 3, 4, 5].map((item, index, arr) => {
  return item * item
})
console.log(m) // [1, 4, 9, 16, 25]

5.檢測數組的方式

const myArray = [1, 3, 5, 7, 9]
const myValue = 1
// 1.使用 instanceof, 判斷該對象的原型鏈上是否有 Array.prototype
console.log(myArray instanceof Array) // true
console.log(myValue instanceof Array) // false
 
// 2.使用 constructor, 注意實例本身是沒有 constructor 屬性的,
//   會從原型鏈上讀取到 Array.prototype (如果是數組)
console.log(myArray.constructor === Array) // true
console.log(myValue.constructor === Array) // false
 
// 3.使用 Object.prototype.toString.call(arr) === '[object Array]'
// 即改變 this 指向, 調用 Object 原型上的 toString 方法
function myIsArray(arr) {
  return Object.prototype.toString.call(arr)
}
let obj = {}
let fn = function() {}
console.log(myIsArray(myArray)) // [object Array]
console.log(myIsArray(myValue)) // [object Number]
console.log(myIsArray(obj))     // [object Object]
console.log(myIsArray(fn))      // [object Function]
 
// 4.ES5 定義了 Array.isArray
console.log(Array.isArray(myArray)) // true

ES6新增

  • Array.from():該方法用於將兩類對象轉換為真正的數組:類似數組的對象(array-like object)和可遍歷(iterable)對象(包括 Set 和 Map)
// NodeList 對象
let ps = document.querySelectorAll('p')
Array.from(ps).forEach(function (p) { // 只有轉換為真正的數組才能使用數組方法
  console.log(p)
})

// arguments對象
function foo () {
  var args = Array.from(arguments)
  // ...
}
  • Array.of():該方法用於將一組值轉換為數組,總是返回參數值組成的數組,如果沒有參數則返回一個空數組
// Array.of 彌補構造函數因參數個數不同而造成的的行為差異
Array.of(3, 11, 8) // [3, 11, 8]
Array.of(3) // [3]
Array.of(3).length // 1

Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
  • copyWithin(target, start, end):在當前數組內部將指定位置的成員復制到其他位置(會覆蓋原有成員),然后返回當前數組。這個方法會修改當前數組
    • target(必選):從該位置開始替換數據
    • start(可選):從該位置開始讀取數據,默認為 0;如果為負數,表示倒數
    • end(可選):到該位置前停止讀取數據,默認等於數組長度
[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]
  • find() 和 findIndex():find 方法用於找出第一個符合條件的數組成員,參數是一個回調函數,所有數組成員依次執行該回調函數,直到找出第一個返回值為 true 的成員,然后返回該成員,如果沒有符合條件的成員,則返回 undefined
  • findIndex() 與 find() 類似,返回的是符合條件的成員的位置,如果都不符合,返回 -1
// 找出數組中第一個大於 9 的成員
// 回調函數可接受 3 個參數:當前的值,當前的位置,原數組
[1, 5, 10, 15].find(function (value, index, arr) {
  return value > 9
}) // 10

[1, 5, 10, 15].findIndex(function (value, index, arr) {
  return value > 9
}) // 2

// 這兩個方法可以發現 NaN,彌補了數組的 IndexOf 方法的不足
[NaN].indexOf(NaN) // -1
[NaN].findIndex(y => Object.is(NaN, y)) // 0
  • fill():fill 方法使用給定值填充一個數組
['a',  'b', 'c'].fill(7) // 7 7 7

// 用於初始化空數組
new Array(3).fill(7) // 7 7 7

// 還可以接受第二個和第三個參數,用於指定填充的起始位置和結束位置
['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']
  • includes():返回一個布爾值,表示某個數組是否包含給定的值
// 第二個參數表示搜索的起始位置,默認為0;如果為負數表示倒數的位置;如果大於數組長度,則會重置為0
[1, 2, 3].includes(3, 3) // false
[1, 2, 3].includes(3, -1) // true

字符串

  • concat():拼接字符串
  • slice(start, end) & substr(start, length) & substring(start, stop):功能類似,記 substr 和 substring 即可,根據是按長度來截取還是按指定下標來進行選擇;不指定第二個參數就是截取從 start 位置到末尾的所有字符串
  • indexOf(value ,index) & lastIndexOf():從一個字符串中搜索給定的子字符串,然后返子字符串的位置(如果沒有找到該子字符串,則返回 -1)區別是從前還是從后開始
  • trim():這個方法會創建一個字符串的副本,刪除前置及后綴的所有空格,然后返回結果;有些瀏覽器還支持非標准的 trimLeft() 和 trimRgiht() 方法
  • toLowerCase() & toLocaleLowerCase() & toUpperCase() & toLocaleUpperCase():大小寫轉換,Lcalel 是針對特定地區的實現。一般來說,在不知道自己的代碼將在哪種語言環境中運行的情況下,還是使用針對地區的方法更穩妥一些
    • 返回一個轉換后的字符串(不影響原字符串),toLowerCase() 是轉換為小寫,toUpperCase()是轉換為大寫
  • split(separator, howmany):基於指定的分隔符將一個字符串分割成多個子字符串,並將結果放在一個數組中
  • match():根據是否全局搜索,返回值會不同
  • search():返回字符串中第一個匹配項的索引;如果沒有找到匹配項,則返回 -1。而且,search() 方法始終是從字符串開頭向后查找模式。
  • replace():用於在字符串中用一些字符替換另一些字符,或替換一個與正則表達式匹配的子串。

較難理解的主要是最后三個模式匹配方法,在左側目錄的“正則表達式”部分中有介紹,這里不再贅述。

ES6 新增

  • codePointAt():對於 2 字節存儲的常規字符而言其返回結果與 charCodeAt() 相同,區別是其該方法能正確處理 4 字節存儲的字符,返回這個字符的碼點
  • fromCodePoint():可識別大於 0xFFFF 的字符,彌補了 String.fromCharCode 方法的不足,作用上與 codePointAt 正好相反
  • at():能正確返回碼點大於 oxFFFF 的字符的位置
  • 遍歷器接口:ES6 為字符串添加了遍歷器接口,使得字符串可以由 for...of 循環遍歷
for (let codePoint of 'foo') {
    console.log(codePoint)
}
// "f"
// "o"
// "o"
// 用 1-9a-zA-Z 生成 5 位隨機數
let arr = []
for (let i = 1; i <= 9; i++) {
  arr.push(i)
}
for (let i = 97; i <= 122; i++) { // a 的 ASCII 碼為 97,z 為 122 -> 'a'.codePointAt(0)
  arr.push(String.fromCodePoint(i)) // 字符轉換成碼點 + 1 后再轉換為字符
}

for (let i = 65; i <= 90; i++) { // A 的 ASCII 碼為 65,Z 為90
  arr.push(String.fromCodePoint(i))
}

let randomString = ''
for (let i = 0; i < 5; i++) {
  let randomIndex = Math.floor(arr.length * Math.random())
  randomString += arr[randomIndex]
}
console.log(randomString)
  • includes():返回布爾值,表示是否找到了參數字符串
  • startsWith():返回布爾值,表示參數字符串是否在源字符串的頭部
  • endsWith():返回布爾值,表示參數字符串是否在源字符串的尾部
var s = 'Hello world'
// 都支持第二個參數,表示開始搜索的位置;endsWith 的行為與其他兩個不同,
// 它針對前 n 個字符,而其他兩個方法針對從第 n 個位置到字符串結束之間的字符
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
  • repeat():返回一個新字符串,表示將原字符串重復 n 次。'x'.repeat(3) // "xxx"
  • padStart() & padEnd():字符串補全長度,padStart 用於頭部補全,padEnd 用於尾部補全;如果某個字符串不夠指定長度,會在頭部或尾部補全
'x'.padStart(5, 'ab') // 'ababx'
'x'.padEnd(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba

// 如果省略第二個參數,則用空格來補全
'x'.padEnd(4) // 'x   '

// 可以這么用
// 為數值補全位數
'12'.padStart(10, '0') // "0000000012"
// 提示字符串格式
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
  • 模板字符串
    • 使用模板字符串表示多行字符串,所有的空格和縮進都會被保留在輸出中
    • 在模板字符串中嵌入變量,需要將變量名寫在 ${}
    • ${fn()}大括號內可以放入任意的 JavaScript 表達式,可以進行運算,以及引用對象屬性,可以調用函數

Map

Map方法 描述
Map() 構造函數
set(key, value) 設置 key 所對應的鍵值,然后返回整個 Map 結構。如果 key 已經有值,則鍵值被更新,否則新生成該鍵
get(key) 讀取 key 對應的鍵值,若未找到 key 則返回 undefined
has(key) 返回一個布爾值,表示某個鍵是否存在於 Map 結構中
delete(key) 刪除某個鍵,返回 true;刪除失敗返回 false
clear() 清除所有成員,沒有返回值
keys() 返回鍵名的遍歷器
values() 返回鍵值的遍歷器
entries() 返回鍵值對的遍歷器
forEach() 使用回調函數遍歷每個成員,用法:map.forEach(function (value, key, map){ })

Set

Set 內部判斷兩個值是否相同使用的算法為“Same-value equality”,它類似於精確相等運算符(===),主要的區別是 NaN 等於自身,而精確相等運算符認為 NaN 不等於自身。

Set方法 描述
Set() 構造函數,可以接受一個數組,或者具有 iterable 接口的其他數據結構作為參數
add(value) 添加某個值,返回 Set 結構本身
delete(value) 刪除某個值,返回布爾值,表示是否刪除成功
has(value) 返回布爾值,表示參數是否為 Set 的成員
clear() 清除所有成員,沒有返回值
keys() 返回鍵名的遍歷器,用法:for (let item of set.keys())
values() 返回鍵值的遍歷器
entries() 返回鍵值對的遍歷器
forEach() 使用回調函數遍歷每個成員

用途:
1.去除數組的重復元素

function dedupe (array){
    return Array.from(new Set(array))
}
console.log(dedupe([1, 1, 2, 3]))  // [1, 2, 3]

2.擴展運算符(...)內部使用 for...of 循環,所以也可以用於 Set 結構,擴展運算符和 Set結構相結合也可以去除數組的重復成員

let arr = [3, 5, 2, 2, 5, 5]
let unique = [...new Set(arr)]
console.log(unique)  // [3, 5, 2]

3.利用 Set 實現並集(Union)、交集(Intersect)、差集(Difference)

let a = new Set([1, 2, 3])
let b = new Set([4, 3, 2])
 
// 並集
let union = new Set([...a, ...b])
console.log(union)  // Set {1, 2, 3, 4}
 
// 交集
let intersect = new Set([...a].filter(x => b.has(x)))
console.log(intersect); // Set {2, 3}
 
// 差集
let difference = new Set([...a].filter(x => !b.has(x)))
console.log(difference)  // Set {1}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM