在線閱讀
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}