let a = ['a','b','c','d','e','f']
console.log(a instanceof Array) // true
複製代碼
let a = ['a','b','c','d''e','f']
Array.isArray(a) // true
複製代碼
let a = ['a','b','c','d''e','f']
Object.prototype.toString.call(a) // [object Array]
複製代碼
var elements = ['A', 'B', 'C']
console.log(elements.join()) // A,B,C
console.log(elements.join('')) // ABC
console.log(elements.join('-')) // A-B-C
複製代碼
var elements = ['A', 'B', 'C']
elements.reverse()
console.log(elements) // ['C','B','A']
複製代碼
sort()方法與reduce()方法結合可用於數組去重。後端
var array1 = [1, 30, 4, 21];
array1.sort();
console.log(array1);// [1, 21, 30, 4]
複製代碼
var array1 = ['a', 'b', 'c']
var array2 = ['a', 'e', 'f']
console.log(array1.concat(array2)) // ["a", "b", "c", "a", "e", "f"]
複製代碼
描述:slice 不修改原數組,只會返回一個淺複製了原數組中的元素的一個新數組。原數組的元素會按照下述規則拷貝:數組
1.若是該元素是個對象引用 (不是實際的對象),slice 會拷貝這個對象引用到新的數組裏。兩個對象引用都引用了同一個對象。若是被引用的對象發生改變,則新的和原來的數組中的這個元素也會發生改變。promise
2.對於字符串、數字及布爾值來講(不是 String、Number 或者 Boolean 對象),slice 會拷貝這些值到新的數組裏。在別的數組裏修改這些字符串或數字或是布爾值,將不會影響另外一個數組。瀏覽器
若是向兩個數組人一中添加了新元素,則另個一不會受到影響。bash
var arr = [1, 2, 3, 4, 5]
arr.slice(0) // [1, 2, 3, 4, 5]
arr.slice(1, 2) // [2]
arr.slice(1, 3) // [2, 3]
淺拷貝的例子:
var myHonda = { color: 'red', wheels: 4, engine: { cylinders: 4, size: 2.2 } };
var myCar = [myHonda, 2, "cherry condition", "purchased 1997"];
var newCar = myCar.slice(0, 2);
console.log('myCar = ' + JSON.stringify(myCar)); // [{color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}, 2,
'cherry condition', 'purchased 1997']
console.log('newCar = ' + JSON.stringify(newCar)); // [{color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}, 2]
console.log('myCar[0].color = ' + JSON.stringify(myCar[0].color)); // red
console.log('newCar[0].color = ' + JSON.stringify(newCar[0].color)); // red
myHonda.color = 'purple';
console.log('The new color of my Honda is ' + myHonda.color); // The new color of my Honda is purple
console.log('myCar[0].color = ' + myCar[0].color); // purple
console.log('newCar[0].color = ' + newCar[0].color); // purple
複製代碼
淺拷貝:上面的demo淺拷貝值值拷貝了數組的第一層,沒有進行深層的拷貝。相似於Object.assign()
app
var arr = [1, 3, 4, 5]
arr.splice(1,0,2) // []
console.log(arr) // [1,2,3,4,5]
arr.splice(4,1) // [5]
console.log(arr) // [1,2,3,4] 刪除5
var months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
console.log(months); // ['Jan', 'Feb', 'March', 'April', 'June']
months.splice(4, 1, 'May') // ['Jan', 'Feb', 'March', 'April', 'May']
複製代碼
語法:dom
開始位置 整數,表示要移除的數組元素的個數 要添加進數組的元素
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
複製代碼
var a = [1,2,3,4,5,6]
for(var i = 0; i < a.length; i++) {
// 在刪除的過程當中數組的index也在動態變化
a.splice(i,1)
}
console.log(a) // [2,4,6]
複製代碼
Array.prototype.slice()與Array.prototype.splice()的區別函數
Array.prototype.slice()與Array.prototype.splice()的區別
slice: 原意爲一塊麪包切下來的薄片。引伸意思爲總體中的一部分.
結合數組的定義,此接口是從數組中切下來的一部分,或者一片,可能片的長度有點大就稱爲一段...
此方法不會改變原數組。是淺拷貝(只拷貝了一層)。
說明:
1.淺拷貝
2.slice()無參數,則拷貝整個數組
3.slice(begin),只有開始入參,即end省略,則表示從begin到arr.length元素都取得。
4.slice(begin,end)取得下標爲[begin, end-1]的元素
5.begin或end爲負值,則表示從數組後端開始計數
splice: 原意爲拼接、結合、粘接(膠片、磁帶等)。將影片或者繩子,使用膠結或者絞接的方式,將其鏈接起來,其鏈接部位稱爲。有一部《SPLICE》的電影(中文名:人獸雜交)。這個故事, 是說兩個科學家, 違反科學道德, 利用人類基因和獸類基因, 作雜交試驗, 生產出一個新的物種, 這個物種就是 雜交(splice), 此雜交是基因序列的 拼接, 進而產生雜交的結果, 產生我的不人,獸不獸的物體。 膠結處、拼接處,即爲splice
splice:改變現有數組內容,其功能包括刪除元素和添加元素。
說明:
1.splice方法改變現有數組內容
2.splice能夠刪除元素和添加元素。刪除和添加 正體現了拼接的要素, 刪除-破壞了現有數組,破壞以後須要進行修補,
修補的結果就是拼接新的數組段,splice 拼接新的數組段, 合併到現有數組中。
這兩個步驟, 多麼相似 電影人獸雜交中基因拼接的標準步驟 (挖掉人類基因中壞的部分, 在這個位置上不上獸類的良好基因), 懷疑js這個接口的定義這, 是收到splice這個電影的啓發。 不然按照英文定義, splice只有拼接的含義, 沒有挖掉的含義, 不該該在此接口中實現挖掉的功能。
3.splice(begin, count), 表示從begin位置開始刪除count個元素。
begin爲負值表示從數組尾部向前計數。 若是 count大於數組的從begin位置計算的元素個數, 則到結束全部的元素都將被刪除
4.splice(begin,0,itema),表示在begin位置後面添加itema元素
5.splice(begin,1,itema,itemb),全功能用法,在begin位置開始刪除一個元素,而後在刪除元素的位置替換上元素 itema 和 itemb。
6.splice返回刪除元素的數組。
複製代碼
var arr = [1,3,5,7]
arr.push(8) // [1,3,5,7,8]
複製代碼
var arr = [1, 2, 3]
console.log(arr.unshift(4, 5)) // 5
console.log(arr) [4, 5, 1, 2, 3]
複製代碼
var arr = [1, 2, 3]
console.log(arr.pop()) // 3
複製代碼
var arr = [1, 2, 3]
console.log(arr.shift()) // [2,3]
複製代碼
for in測試
var arr = [1, 2, 3]
for (var i in arr) {
console.log(arr[i])
}
// 1
// 2
// 3
var obj = {a:1; b:2; c:3}
for (var i in arr) {
console.log(obj[i])
}
// 1
// 2
// 3
複製代碼
for of 循環可使用的範圍包括數組、Set 和 Map 結構、某些相似數組的對象等。ui
const arr = [1, 2, 3];
for(let v of arr) {
console.log(v);
}
// 1
// 2
// 3
複製代碼
map() 方法建立一個新數組,其結果是該數組的每個元素都調用一個提供的函數後返回的結果。map()方法在必定程度上就是爲生成新數組而生的
var arr = [1,2,3]
var mapArr = arr.map(x => x * 3)
console.log(mapArr) // [1,6,9]
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots的值爲[1, 2, 3], numbers的值仍爲[1, 4, 9]
複製代碼
forEach() 方法對數組的每個元素執行一次提供的函數。
var arr = [1,2,3]
arr.forEach(function(item,index,arr){
console.log(`arr[${index}]=${item}`)
})
// arr[0]=1
// arr[1]=2
// arr[2]=3
複製代碼
將for循環改成forEach
const items = ['item1', 'item2', 'item3']
const copy = []
// for 循環
for (let i = 0; i< items.length; i++) {
copy.push(items[i])
}
// forEach
items.forEach(function(item){
copy.push(item)
})
複製代碼
若是數組在迭代時被修改了,則其它元素會被跳過
let words = ['one','two','tree','four']
words.forEach(function(word) {
console.log(word)
if (word === 'two') {
words.shift()
}
})
// one
// two
// four
當到達包含值"two"的項時,整個數組的第一個項被移除了,這致使全部剩下的項上移一個位置。由於元素"four"如今在數組更新前的位置,"tree"會被跳過。forEach()不會在迭代以前建立數組的副本。
複製代碼
對於數組和可迭代對象的遍歷方法,咱們須要從不一樣的維度進行對比,方法的功能性,方法的應用場景,方法的兼容性,方法的效率,方法的返回值以及是是否改變原始數組。這些方法是如何實現的,而且考慮低版本瀏覽器的兼容性。 forEach()與map()
,every()與some()
,filter()與find()、findIndex()
,keys()、values()與entries()
,reduce()與reduceRight()
js遍歷方法
ES5方法:
forEach arr.forEach(fn,thisArg) 返回undefined
map arr.map(fn,thisArg) 返回新數組
every arr.every(fn,thisArg) 返回true或false,一假即爲假
some arr.some(fn,thisArg) 返回true或false,一真即爲真
filter arr.filter 返回新數組
reduce 返回一個值
reduceRight 返回一個值
for-in 循環獲得key
ES6方法
for-of 用於循環數組,循環獲得value
find & findIndex arr.find(fn,thisArg),arr.findIndex(fn,thisArg) 返回數組中第一個知足條件的元素(元素的索引),若是沒有則返回undefined(或-1)
entries arr.entries() 返回一個數組迭代器對象
keys arr.keys() 返回一個數組索引的迭代器
values arr.values() 返回一個數組迭代器對象,該對象包含數組中每一個索引的值
Symbol.iterator 返回一個數組迭代器對象 arrSymbol.interator
var arr = [1,2,3]
const result = arr.filter(x => x >1)
console.log(result) // [2,3]
複製代碼
var arr = [1,2,3]
var even = arr.some(x => x > 5) // false
複製代碼
var arr = [1,2,3]
var passed = arr.every(x => x < 5) // true
複製代碼
reducer函數接收4個參數:
語法
arr.reduce(callback[, initialValue])
複製代碼
參數:
reduce
爲數組中的每個元素執行callback函數,不包括數組中被刪除或從未被賦值的元素。var arr = [1,2,3,4]
var reducer = arr.reduce((accumulator,currentValue) => accumulator * currentValue) // 24
複製代碼
數組求和
var sum = arr.reduce((accumulator,currentValue) => accumulator + currentValue) // 10
複製代碼
找出數組中最大值
var max = arr.reduce((accumulator,currentValue) => accumulator > currentValue ? accumulator : currentValue) // 4
複製代碼
找出數組中最小值
var min = arr.reduce((accumulator,currentValue) => accumulator < currentValue ? accumulator : currentValue) // 1
複製代碼
累加對象數組裏的值
let initialValue = 0
let sum = [{x: 1},{x: 2},{x: 3}].reduce((accumulator, currentValue) => accumulator + currentValue.x), initialValue)
console.log(sum) // 6
複製代碼
將二維數組轉化爲一維
let flattened = [[0,1],[2,3],[4,5]].reduce((acc,cur) => acc.concat(cur), []) // [0,1,2,3,4,5]
複製代碼
計算數組中每一個元素出現的次數
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
let countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
}
else {
allNames[name] = 1;
}
return allNames;
}, {})
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
複製代碼
按屬性對object分類
const people = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
]
function groupBy (objectArray, property) {
return objectArray.reduce(function (acc, obj) {
let key = obj[property]
if (!acc[key]) {
acc[key] = []
}
acc[key].push(obj)
return acc
},{})
}
let gruupedPeople = groupBy(people, 'age')
// {
// 20: [
// { name: 'Max', age: 20 },
// { name: 'Jane', age: 20 }
// ],
// 21: [{ name: 'Alice', age: 21 }]
// }
複製代碼
數組去重
let arr = [1,2,1,2,3,5,4,5,3,4,3,4,4,4,4]
let result = arr.sort().reduce((init, current)=> {
if(init.length===0 || init[init.length-1] !== current) {
init.push(current)
}
return init
},[])
console.log(result) // [1,2,3,4,5]
複製代碼
編寫一個函數 unique(arr),返回一個去除數組內重複的元素的數組。例如:
unique([0, 1, 2, 2, 3, 3, 4]) // => [0, 1, 2, 3, 4]
unique([0, 1, '1', '1', 2]) // => [0, 1, '1', 2]
const unique = (arr) => {
let result = arr.reduce((init, current) => {
if (init.indexOf(current) === -1) {
init.push(current)
}
return init
},[])
return result
}
var testArr = [1, '1', 1, '1', '1', '2', 2, 2, '2', 3, 3, 3]
unique(testArr)
複製代碼
const unique = (arr) => [...new Set(arr)]
複製代碼
數組去重
function merge(arr) {
if (!Array.isArray(arr) || arr.length == 0 ) return []
var ret = []
for (var i = 0; i < arr.length; i++) {
// 或者 arr.indexOf(arr[i]) == i)
if (ret.indexOf(arr[i] == -1) {
ret.push(arr[i])
}
}
return ret
}
複製代碼
按順序運行Promise
/**
* Runs promises from array of functions that can return promises
* in chained manner
*
* @param {array} arr - promise arr
* @return {Object} promise object
*/
function runPromiseInSequence(arr, input) {
return arr.reduce(
(promiseChain, currentFunction) => promiseChain.then(currentFunction),
Promise.resolve(input)
);
}
// promise function 1
function p1(a) {
new Promise(resolve, reject) {
resolve(a * 5)
}
}
// promise function 2
function p2(a) {
return new Promise((resolve, reject) => {
resolve(a * 2);
});
}
// function 3 - will be wrapped in a resolved promise by .then()
function f3(a) {
return a * 3;
}
// promise function 4
function p4(a) {
return new Promise((resolve, reject) => {
resolve(a * 4);
});
}
const promiseArr = [p1, p2, f3, p4];
runPromiseInSequence(promiseArr, 10)
.then(console.log); // 1200
複製代碼
功能型函數管道
// Building-blocks to use for composition
const double = x => x + x;
const triple = x => 3 * x;
const quadruple = x => 4 * x;
// Function composition enabling pipe functionality
const pipe = (...functions) => input => functions.reduce(
(acc, fn) => fn(acc),
input
);
// Composed functions for multiplication of specific values
const multiply6 = pipe(double, triple);
const multiply9 = pipe(triple, triple);
const multiply16 = pipe(quadruple, quadruple);
const multiply24 = pipe(double, triple, quadruple);
// Usage
multiply6(6); // 36
multiply9(9); // 81
multiply16(16); // 256
multiply24(10); // 240
複製代碼
Polyfill
if (!Array.prototype.reduce) {
Object.defineProperty(Array.prototype, 'reduce', {
value: function(callback) {
if (this === null) {
throw new TypeError('Array.prototype.reduce ' +
'called on null or undefined' )
}
if (typeof callback !== 'function') {
throw new TypeError( callback +
' is not a function')
}
// 1. Let O be ? ToObject(this value).
var o = Object(this)
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// Steps 3, 4, 5, 6, 7
var k = 0;
var value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < len && !(k in o)) {
k++;
}
// 3. If len is 0 and initialValue is not present,
// throw a TypeError exception.
if (k >= len) {
throw new TypeError( 'Reduce of empty array ' +
'with no initial value' );
}
value = o[k++];
}
// 8. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kPresent be ? HasProperty(O, Pk).
// c. If kPresent is true, then
// i. Let kValue be ? Get(O, Pk).
// ii. Let accumulator be ? Call(
// callbackfn, undefined,
// « accumulator, kValue, k, O »).
if (k in o) {
value = callback(value, o[k], k, o);
}
// d. Increase k by 1.
k++;
}
// 9. Return accumulator.
return value;
}
})
}
複製代碼
若是您須要兼容不支持Object.defineProperty的JavaScript引擎,那麼最好不要 polyfill Array.prototype方法,由於你沒法使其成爲不可枚舉的。
const arr = [[1,2],[3,4],[5,6]]
const result = arr.recudeRight((accumulator,currentValue) => accumulator.concat(currentValue))
console.log(result) // [5,6,3,4,1,2]
複製代碼
reduce()與reduceRight()的區別
var a = ['1', '2', '3', '4', '5'];
var left = a.reduce(function(prev, cur) { return prev + cur; });
var right = a.reduceRight(function(prev, cur) { return prev + cur; });
console.log(left); // "12345"
console.log(right); // "54321"
複製代碼
let arr = [1,2,3]
複製代碼
方法1
建立臨時變量
let temp = arr[0]
arr[0] = arr[2]
arr[2] = temp
複製代碼
方法2
ES6解構賦值
[arr[0],arr[2]] = [arr[2],arr[0]]
複製代碼
方法3
splice方法,此方法會以數組返回原數組被修改的內容。
arr.splice(2,1, ...arr.splice(0,1, arr[2]))
注:arr.splice(0,1, arr[2]) // [1] 此時數組爲 [3,2,3]
arr.splice(2,1,1) // 數組交換位置完成 [3,2,1]
複製代碼
var arr = [1,2,3,4,5,6]
arr.sort(() => {
return 0.5 - Math.random()
})
console.log(arr) // [4, 6, 1, 2, 3, 5]
上面的寫法並非真正意義上的徹底亂序,在抽獎的需求中,這樣寫會出大問題。
複製代碼
const arr = [1, 2, 3, 4, 5, 6]
for (let i = 1; i < arr.length; i++) {
const random = Math.floor(Math.random() * (i + 1))
[arr[i], arr[random]] = [arr[random], arr[i]]
}
複製代碼
undefined
var array1 = [5, 12, 8, 130, 44];
var found = array1.find(function(element) {
return element > 10;
});
console.log(found); // 12
複製代碼
Array.from(arrayLike[, mapFunction[, thisArg]])
複製代碼
生成數字範圍
function range(end) {
return Array.from({ length: end}, (_, index) => index)
}
range(6) // [0, 1, 2, 3, 4, 5]
複製代碼
在range()
函數中,Array.from()
提供了相似數組的{length: end}
,以及一個簡單返回當前索引的map
函數。將索引值index
組合成了一個新的數組。作法很是的巧妙。
Array.from({ length: 6})
返回的結果以下:
Array.from({ length: 6}) // [undefined, undefined, undefined, undefined, undefined, undefined]
複製代碼
數組去重
因爲 Array.from()
的入參是可迭代對象
,於是咱們能夠利用其與 Set
結合來實現快速從數組中刪除重複項。
function unique(array) {
return Array.from( new Set(array) )
}
unique([1,2,2,4,3,5,3]) // [1,2,4,3,5]
複製代碼
new Set(array)
建立了一個包含數組的集合,並刪除重複項
由於 Set
集合是可迭代的,因此可使用 Array.from()
將其轉換爲一個新的數組。
24.Array.prototype.flatMap()
flatMap()
方法首先使用映射函數映射每一個元素,而後將結果壓縮成一個新數組。它與map
和深度值1的flat
幾乎相同,但flatMap
一般在合併成一種方法的效率稍微高一些。
var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
// 返回新數組的元素
}[, thisArg]
複製代碼
返回值:一個新的數組,其中每一個元素都是回調函數的結果,而且結構深度depth
值爲1.
var arr1 = [1, 2, 3, 4]
arr1.map(x => [x * 2]) // [[2], [4], [6], [8]]
arr1.flatMap(x => [x * 2]) // [2, 4, 6, 8]
// 只會將 flatMap 中的函數返回的數組「壓平」一層
arr1.flatMap(x => [[x * 2]]) // [ [2], [4], [6], [8]]
複製代碼
雖然上面的代碼使用 map 和 flatMap 好像均可以,但這隻能展現如何使用 flatMap。
因此,爲了更好的展現flatMap
的做用,咱們將包含幾句話的數組拆分紅單個漢字組成的新數組。
let arr = ["今每天氣不錯","","早上好"]
arr.map(s => s.split("")) // [["今", "天", "天", "氣", "不", "錯"],[],["早", "上", "好"]]
arr.flatMap(s => s.split('')) // ["今", "天", "天", "氣", "不", "錯", "早", "上", "好"]
複製代碼
等價操做
概括(reduce)與合併 (concat)
var arr1 = [1, 2, 3, 4]
arr1.flatMap(x => [x * 2])
// 等價於
arr1.reduce((acc, x) => acc.concat([x * 2]), []) // [2, 4, 6, 8]
複製代碼