這是《前端總結·基礎篇·JS》系列的第二篇,主要總結一下JS數組的使用、技巧以及經常使用方法。html
1、數組使用 1.1 聲明數組 1.2 訪問數組 1.3 類型檢測 2、經常使用技巧 2.1 數組去重 2.2 數組深拷貝 2.3 字符串反序 3、方法列表 3.1 存取 3.2 字符串 3.3 修改 3.4 ES5 3.5 ES2015(ES6) 3.6 ES2016
數組不是基本數據類型,可是很是經常使用,因此提早總結。前端
基本數據類型是String,Number,Boolean,null,undefined。git
數組用中括號括起來,不一樣的值用逗號隔開。數組內的值有字符串須要用單引號或者雙引號引發來。es6
var arr = [] // 聲明一個空數組 var arr = [3,6,8,9] // 聲明一個包含值3,6,8,9的數組 var arr = new Array(3,6,8,9) // 建立一個數組對象
下標訪問github
數組的下標是從0開始的,最後一個值的下標是數組長度減去1。訪問數組能夠直接訪問具體下標的一個值,也能夠直接訪問整個數組的值。web
var arr = [1,2,3,4] console.log(arr) // 直接訪問數組 | [1, 2, 3, 4] console.log(arr[0]) // 經過下標訪問 | 1 console.log(arr.length) // 訪問數組的長度 | 4
遍歷訪問後端
若是須要逐個的訪問數組中的值,你須要對數組進行遍歷。能夠用通常的for循環、for in或者ES6中的for of。跨域
var arr = [1,2,3,4] // for for(var x = 0; x < arr.length; x++){ console.log(arr[x]) // 經過下標訪問 } // for in for(x in arr){ console.log(arr[x]) // 經過下標訪問 } // for of (ES6) for(x of arr){ console.log(x) // 不須要經過下標訪問 }
檢測一個對象有如下方法。更精確的檢測數組請見請見jwalden數組
* typeof [] // object * [] instanceof Array // false * Array.isArray([]) // true | 一般用來檢測數組 * Array.isArray(Array.prototype) // true | 這是一個例外狀況
能夠用concat/push合併。concat返回合併後的新數組,push保存在原數組裏。app
感謝園友 @loveyatou 提醒。在push方法中把apply寫成了call,致使結果不符合預期。現已修正。 2017/03/17 13:45
PS:call和apply都是用來改變函數做用域的,用法基本一致,惟獨傳遞參數的方法不一致。call是逐個輸入,逗號隔開。apply是所有放在一個數組內。
var a = [1,2,3] var b = [4,5,6] // concat 方法 var c = a.concat(b) console.log(c) // [1, 2, 3, 4, 5, 6] // push 方法 Array.prototype.push.apply(a,b) console.log(a) // [1, 2, 3, 4, 5, 6]
咱們能夠根據concat/slice方法返回新數組的特性來進行深拷貝,也能夠直接用循環語句暴力深拷貝。
// 深拷貝前 var arr = [1,2,3,4] var newArr = arr // 把原數組賦值給新數組 arr.pop() // 刪除原數組的一個值 console.log(arr) // 測試原數組的值 [1, 2, 3] console.log(newArr) // 測試新數組的值 [1, 2, 3] // 深拷貝後 var arr = [1,2,3,4] var newArrCopy = arr.concat() // 開始深拷貝,此處也可使用arr.slice() arr.pop() // 刪除原數組的一個值 console.log(arr) // 測試原數組的值 [1, 2, 3] console.log(newArrCopy) // 測試新數組的值 [1, 2, 3, 4] // 暴力深拷貝 var arr = [1,2,3,4] var newArr = [] // 爲了使用數組的push方法,必定要定義數據類型爲數組 for (var x = 0; x < arr.length; x++){ newArr.push(arr[x]) // 用循環逐個把值保存在新數組內 } arr.pop() // 刪除原數組的一個值 console.log(arr) // 測試原數組的值 [1, 2, 3] console.log(newArr) // 測試新數組的值 [1, 2, 3, 4]
排序後去重,更多請見腳本之家
var newArr = arr.sort() // 排好序再比較 var newArrSaved = [newArr[0]] // 初始化爲數組,用來存儲最後的數據 for(var i =2;i<arr.length;i++){ // 從第二個開始 if(newArr[i]!==newArr[i-1]) // 判斷當前值和上一個值是否一致 newArrSaved.push(newArr[i]) // 不一致則存在newArrSaved }
首先將字符串序列化成數組,經過數組方法對數組反序,最後把數組轉換成字符串。
'I See U.'.split('').reverse().join('') // ".U eeS I"
ES5和ES6部分就看成參考手冊吧,有時間再琢磨一下應用場景。
如下實例在此基礎上進行
arr = [1,2,3,4]
push在尾部添加,pop從尾部刪除。
尾存取
push(element1, ..., elementN) * arr.push(8) // [1, 2, 3, 4, 5] pop() * arr.pop() // [1, 2, 3, 4]
首存取
unshift在首部添加,shift從首部刪除。
unshift(element1, ..., elementN) * arr.unshift(5) // [5, 1, 2, 3, 4] shift * arr.shift() // [1, 2, 3, 4]
字符串
join默認以逗號分隔鏈接的字符串,傳入參數能夠進行自定義分割方式。
toString() * arr.toString() // "1,2,3,4" toLocalString() * arr.toLocalString() // 和上面的效果一致,此方法僅在特殊語言中須要 join(separator) * arr.join() // "1,2,3,4" * arr.join('') // "1234" * arr.join('-') // "1-2-3-4"
排序
reverse把數組顛倒,sort對數組排序。sort默認按照unicode排序,傳入function(a,b)能夠自定義排序。更多請見MDN(內有對象按屬性值排序的方法)
reverse() * arr.reverse() // [4, 3, 2, 1] sort() * arr.sort() // [1, 2, 3, 4] 這個已經排好了序,因此不變
鏈接
concat鏈接數組,並返回一個新的數組。
concat(value1[, value2[, ...[, valueN]]]) arr.concat(9) // [1, 2, 3, 4, 9]
切割
切割比上面的稍微複雜點
slice爲提取元素,splice爲刪除指定範圍元素並添加新元素。slice的第二個參數,是結束的位置標記,不會包括在返回值內。
slice的返回值是提取元素組成的新數組。splice的返回值是刪除元素組成的新數組,原始元素被修改。
slice在IE<9下使用時,會出現一些問題,須要使用膩子腳本。詳見MDN
slice(begin,end) * arr.slice(1,3) // [2, 3] splice(start, deleteCount, item1, item2, ...) * arr.splice(1,3,5) // [2, 3, 4] 返回值 * console.log(arr) // [1, 5] 原始元素被修改
須要精確檢測數組請見jwalden
數組檢查 Array.isArray(obj) // 檢查是否爲數組,返回值爲true/false,兼容IE9+ * Array.isArray([1,2,3]) // true * Array.isArray('123') // false * Array.isArray(Array.prototype) // true arr.every(callback[, thisArg]) * function isNotZero(element, index, array){return element!==0} * arr.every(isNotZero) // true arr.map(callback[, thisArg]) // 每一個值都調用一次函數而且返回新數組 * function twice(element, index, array){return element*element} * arr.map(twice) // [1, 4, 9, 16] arr.reduce(callback,[initialValue]) // 將多維數組轉爲一維數組 arr.some(callback[, thisArg]) // 測試元素是否經過指定測試 arr.indexOf(searchElement[, fromIndex = 0]) // 返回知足條件的第一個索引,不存在返回-1 * arr.indexOf(3) // 2 arr.lastIndexOf(searchElement[, fromIndex = arr.length - 1]) // 由後向前查找 arr.forEach(callback[, thisArg]) // 對數組每一個元素執行一次函數
Array.of(element0[, element1[, ...[, elementN]]]) // 建立新數組 * Array.of(3) // [3] * Array(3) // [undefined × 3] * Array.of([1,2,3]) // [Array[3]] * Array([1,2,3]) // [Array[3]] Array.from(arrayLike[, mapFn[, thisArg]]) // 從類數組對象或可遍歷對象中建立數組 * Array.from('berg') // ["b", "e", "r", "g"] arr.copyWithin(target, start, end) // 選定數組值,在必定範圍內所有粘貼選定值 * arr.copyWithin(1,2,3) // [1, 3, 3, 4] arr.entries() // 返回新的數組迭代器(必定得複製給變量再迭代) * var newArr = arr.entries() * newArr.next().value // [0, 1] * newArr.next().value // [1, 2] * newArr.next().value // [2, 3] * newArr.next().value // [3, 4] arr.keys() // 返回新的數組迭代器 arr.fill(value, start, end) // 用指定值填充必定範圍數組 * arr.fill(0,1,3) // [1, 0, 0, 4] arr.filter(callback[, thisArg]) // 將知足條件的元素返回成新數組 * function isNotZero(element){return element!==0} * arr.filter(isNotZero) // [1, 2, 3, 4] arr.find(callback[, thisArg]) // 返回知足條件的第一個值,不存在返回undefined * function isNotZero(element){return element!==0} * arr.find(isNotZero) // 1 arr.findIndex(callback[, thisArg]) // 返回知足條件的第一個元素的索引 * function isNotZero(element){return element!==0} * arr.findIndex(isNotZero) // 0
arr.includes(searchElement, fromIndex) // 判斷數組是否包含指定值,返回true/false arr.includes(2) // true
文章主要參考的站點
ES5
前端兼容性方案