溫故js系列(16)-數組&數組方法使用詳解

前端學習:前端教程&開發模塊化/規範化/工程化/優化&工具/調試&值得關注的博客/Git&面試-前端資源彙總前端

歡迎提issues斧正:數組&數組方法使用詳解git

Array對象

以前一直在溫故js系列,但願可以知新,不過最近應業務要求,在作移動WEB,需求大,任務多。因此,只有像如今閒着的時候才能繼續溫故js了。祖國母親的生日,祝祖國繁榮昌盛O(∩_∩)O~ 不知道有多少程序猿宅在家裏,多少程序猿堵在路上...es6

在 JavaScript 中 Array 是一個用來構造數組的全局對象,它是一個高階的相似有序列表的對象,是JavaScript內置對象裏很是重要的一個。github

建立數組:面試

數組字面量

var arr = []; 
var arr = [1, 2, 3];
var arr = [[1],2,[2,[123]]];

數組構造函數

var arr = new Array();  //[]
var arr = new Array(1,2,3); //[1, 2, 3]
var arr = new Array(3);  //[undefined,undefined,undefined] 參數3爲數組length
var arr = new Array([1],2,[2,[123]]); //[[1],2,[2,[123]]]

建議使用數組字面量方式,性能好,代碼少,簡潔,畢竟代碼少。segmentfault

Array屬性

length屬性

length屬性返回數組的長度,是一個可變屬性,表示一個數組中的元素個數。
數組的索引由0開始,因此一個數組的最前和最後的值爲限分別是:arr[0]arr[arr.length-1]數組

var arr = [1,2,3];
arr.length // 3
arr.length = 2; //改變數組length,從後往前截取
arr // [1,2],此時arr.length爲2。因此平時咱們能夠用length來操做數組(刪除,添加)
arr.length = 4;
arr // // [1,2,undefined,undefined],此時arr.length爲2,後面填充undefined

prototype屬性

prototype屬性返回對象類型原型的引用,全部的數組實例都繼承了這個屬性,全部的數組方法都定義在 Array.prototype 身上。通常來講,咱們常常用prototype屬性來擴展數組方法:app

//給數組添加個方法,返回數組中的最大值
Array.prototype.max = function() {
    return Math.max.apply(null,this); 
}
[1,2,3,4].max(); //4

//給數組添加個方法,給數組去重
Array.prototype.unique = function() {
    return this.filter((item, index, arr) => arr.indexOf(item) === index);
}
[11,2,1,1,2,3,1,2,4,5,23,2].unique(); //[11, 2, 1, 3, 4, 5, 23]

數組去重:數組去重演化模塊化

constructor屬性

constructor屬性返回建立對象的函數,即構造函數。以下:函數

var arr = [1,2,3];
arr.constructor  //function Array() { [native code] }
arr.constructor === Array  //true  即 new Array
var a = new Array();
a.constructor === Array  //true

對於數組來講,這個屬性仍是罕見使用的。

數組判斷

Array.isArray()

Array.isArray() 方法用來判斷某個值是否爲Array。若是是,則返回 true,不然返回 false

Array.isArray([]);  //true
Array.isArray([1,2,3]);  //true
Array.isArray(new Array());  //true
Array.isArray();  //false
Array.isArray({});  //false
Array.isArray(123);  //false
Array.isArray('xzavier');  //false

利用屬性本身寫方法

Array.isArray()在ES5以前不支持,就本身寫。不過如今都到ES6了,能夠無論了。

Array.prototype.isArray = Array.prototype.isArray || function() {
    return Object.prototype.toString.call(this) === "[object Array]";
}
[1,2,3].isArray(); //true

數組遍歷

關於這幾個遍歷語句的詳細講解可參考:溫故js系列(8)-流程控制

經典的for

for (var index = 0; index < arr.length; index++) {
    console.log(arr[index]);
}

這種寫法很經典,就是語句多,可是性能好。

ES5的forEach

arr.forEach(function (value) {
    console.log(value);
});

這種寫法簡潔,但這種方法也有一個小缺陷:你不能使用break語句中斷循環,也不能使用return語句返回到外層函數。

不建議的for-in

for (var i in arr) { 
    console.log(arr[i]);
}

for-in是爲普通對象設計的,你能夠遍歷獲得字符串類型的鍵,所以不適用於數組遍歷。可是它能遍歷數組,做用於數組的for-in循環體除了遍歷數組元素外,還會遍歷自定義屬性。舉個例子,若是你的數組中有一個可枚舉屬性arr.name,循環將額外執行一次,遍歷到名爲「name」的索引。就連數組原型鏈上的屬性都能被訪問到。因此,不建議使用。

ES6的for-of

for (var value of arr) {
    console.log(value); // 1 2 3 
}

這是最簡潔、最直接的遍歷數組元素的語法。這個方法避開了for-in循環的全部缺陷。與forEach()不一樣的是,它能夠正確響應break、continue和return語句。

for (var value of arr) {
    if(value == 2){break;}
    console.log(value);  //1
}

數組方法細說

splice插入、刪除、替換

splice() 方法能夠插入、刪除或替換數組的元素,注意:同時改變了原數組

1.刪除-刪除元素,傳兩個參數,要刪除第一項的位置和第二個要刪除的項數
2.插入-向數組指定位置插入任意項元素。三個參數,第一個參數(位置),第二個參數(0),第三個參數(插入的項)
3.替換-向數組指定位置插入任意項元素,同時刪除任意數量的項,三個參數。第一個參數(起始位置),第二個參數(刪除的項數),第三個參數(插入任意數量的項)

var arr = ["q","w","e"]; 
//刪除 
var removed = arr.splice(1,1); 
console.log(arr); //q,e  已被改變
console.log(removed); //w ,返回刪除的項 
//插入 
var insert = arr.splice(0,0,"r"); //從第0個位置開始插入 
console.log(insert); //返回空數組 
console.log(arr); //r,q,e 
//替換 
var replace = arr.splice(1,1,"t"); //刪除一項,插入一項 
console.log(arr); //r,t,e
console.log(replace); //q,返回刪除的項

sort 排序

sort() 方法對數組的元素作原地的排序,並返回這個數組。

var arr = [1,2,4,3,1,1,2];
console.log(arr.sort());//[1, 1, 1, 2, 2, 3, 4]

然而:
var arr = [1,2,10,4,3,1,1,2];
console.log(arr.sort());//[1, 1, 1, 10, 2, 2, 3, 4]

這是由於sort排序多是不穩定的,默認按照字符串的Unicode碼位點排序。

可是,sort()方法接受一個參數,這個參數是一個函數,可選,用來指定按某種順序進行排列的函數。若是省略,元素按照轉換爲的字符串的諸個字符的Unicode位點進行排序。

var arr = [1,2,10,4,3,1,1,2];
console.log(arr.sort(function(a,b){
    return a-b; 
})); // [1, 1, 1, 2, 2, 3, 4, 10]

這個函數就是咱們本身控制了,咱們想要什麼樣的排序就改變這個參數函數的邏輯便可。

slice截取、轉化arguments僞數組

slice()方法可從已有的數組中返回選定的元素數組。不會修改原數組,只會會淺複製數組的一部分到一個新的數組,並返回這個新數組。

語法:arrayObject.slice(start,end) 參數可爲正負。

start    必需。規定從何處開始選取。若是是負數,那麼它規定從數組尾部開始算起的位置。也就是說,-1 指最後一個元素,-2 指倒數第二個元素,以此類推。
end      可選。規定從何處結束選取。該參數是數組片段結束處的數組下標。若是沒有指定該參數,那麼切分的數組包含從 start 到數組結束的全部元素。
         若是這個參數是負數,那麼它規定的是從數組尾部開始算起的元素。

var arr = [1,2,3,4,5];
arr.slice(0,3);    //  [1,2,3]
arr.slice(3);      //  [4,5]
arr.slice(1,-1);   //  [2,3,4]
arr.slice(-3,-2);  //  [3]
var arr1 = arr.slice(0); //返回數組的拷貝數組,是一個新的數組,不是賦值指向

slice方法常常用來截取一個數組,不過它更經常使用在將僞數組轉化爲真數組。平時咱們的函數傳的參數arguments是一個僞數組,不少數組的方法不能使用,咱們就須要將僞數組轉化爲真數組。

function test() {
    var arr = arguments;
    arr.push('xza');
    console.log(JSON.stringify(arr));
}
test(1,2,3);  //arr.push is not a function(…) 由於僞數組沒有push方法

轉換後:
function test() {
    var arr = Array.prototype.slice.call(arguments);
    arr.push('xza');
    console.log(JSON.stringify(arr));
}
test(1,2,3); //[1,2,3,"xza"]

filter 過濾

filter() 方法使用指定的函數測試全部元素,並建立一個包含全部經過測試的元素的新數組。簡單來講就是對數組進行過濾,返回一個過濾過的數組。

語法:array.filter(function(currentValue,index,arr), thisValue)

function(currentValue, index,arr)    必須。函數,數組中的每一個元素都會執行這個函數

函數的三個參數:currentValue必須,當前元素的值; index可選,當期元素的索引值; arr可選,當期元素屬於的數組對象
thisValue    可選。對象做爲該執行回調時使用,傳遞給函數,用做 "this" 的值。若是省略了 thisValue ,"this" 的值爲 "undefined"

//用filter給數組添加個方法,給數組去重
Array.prototype.unique = function() {
    return this.filter((item, index, arr) => arr.indexOf(item) === index);
}
[11,2,1,1,2,3,1,2,4,5,23,2].unique(); //[11, 2, 1, 3, 4, 5, 23]

filter() 不會對空數組進行檢測,不會改變原始數組。

concat 鏈接數組

var arr1 = [1,2,3];
var arr2 = [4,5,6];
var arr3 = arr1.concat(arr2);  //[1, 2, 3, 4, 5, 6]
arr3.concat(7); //[1, 2, 3, 4, 5, 6, 7]

咱們平時都是這麼使用的,若是須要鏈接兩個數組的元素時,中間插元素,能夠

var arr3 = arr1.concat('xzavier', arr2); //[1, 2, 3, "xzavier", 4, 5, 6]

不加參數至關於拷貝,返回數組的拷貝數組,是一個新的數組,並非指向原來數組。

var arr4 = arr1.concat(); //[1,2,3]
var arr5 = arr1;
arr4 === arr1; //false
arr5 === arr1; //true

插入刪除

前面講了個splice能夠在數組的任何位置插入刪除元素,這兒講的是隻能在首尾插入刪除的方法,用起來也很方便。

在數組尾插入刪除:

push()方法能夠接收任意數量的參數,把它們逐個添加到數組的末尾,並返回修改後數組的長度。
pop()方法則從數組末尾移除最後一個元素,減小數組的length值,而後返回移除的元素。

var arr  = [1,2,3];
arr.push(4);  // 返回的length 4
arr.pop();   //返回的刪除值  4
arr  //[1, 2, 3]

在數組頭插入刪除:

unshift()方法爲數組的前端添加一個元素
shift()方法從數組前端移除一個元素

var arr  = [1,2,3];
arr.unshift(4);  // 返回的length 4
arr.shift();   //返回的刪除值  4
arr  //[1, 2, 3]

其餘方法

方法                使用
concat()         鏈接兩個或更多的數組,並返回結果。
join()           把數組的全部元素放入一個字符串。元素經過指定的分隔符進行分隔。
reverse()        顛倒數組中元素的順序。
toString()       把數組轉換爲字符串,並返回結果。
toLocaleString() 把數組轉換爲本地數組,並返回結果。
valueOf()        返回數組對象的原始值
map()            返回一個由原數組中的每一個元素調用一個指定方法後的返回值組成的新數組。
every()          測試數組的全部元素是否都經過了指定函數的測試。
some()           測試數組中的某些元素是否經過了指定函數的測試。

小試:(歡迎補充和斧正問題,更多方法延伸閱讀:ES6數組的擴展

ar arr = ['xzavier',123,'jser'];
console.log(arr.valueOf());  //['xzavier',123,'jser']
console.log(arr.toString());  //xzavier,123,jser
console.log(arr.toLocaleString());  //xzavier,123,jser
var arr = ['xzavier',123,'jser'];
console.log(arr.join(','));     //xzavier,123,jser
var arr = [1,2,3];
console.log(arr.reverse());     //[3,2,1]
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt); //[1,2,3]
numbers //[1,4,9]
roots // [1,2,3]
[2, 5, 1, 4, 3].some(function (element, index, array) {
    return (element >= 10);
});  //false
[2, 5, 1, 4, 13].some(function (element, index, array) {
    return (element >= 10);
});  //true
[2, 5, 1, 4, 13].every(function (element, index, array) {
    return (element >= 10);
});  //false
[2, 5, 1, 4, 13].every(function (element, index, array) {
    return (element >= 0);
});  //true

趣味探索

[1,2] + [3,4] == "1,23,4";  //true
++[[]][+[]]+[+[]] == '10';  //true
console.log ([] == ![]);    //true
相關文章
相關標籤/搜索