摘要:數(shù)組的特別之處在于,當(dāng)使用小于的非負(fù)整數(shù)作為屬性名時數(shù)組會自動維護(hù)其屬性值。返回的數(shù)組包含第一個參數(shù)指定的位置和所有到但不含第二個參數(shù)指定的位置之間的所有數(shù)組元素。數(shù)組中只需有一項滿足給定條件則返回。
概念
JavaScript數(shù)組是JavaScript對象的特殊形式。數(shù)組索引實際上和碰巧是整數(shù)的屬性名差不多,使用方括號訪問數(shù)組元素就像用方括號訪問對象的屬性一樣。JavaScript將指定的數(shù)字索引值轉(zhuǎn)換成字符串——索引值1變成 “1”——然后將其作為屬性名來使用。
數(shù)組的特別之處在于,當(dāng)使用小于2^32的非負(fù)整數(shù)作為屬性名時數(shù)組會自動維護(hù)其length屬性值。通常,數(shù)組的實現(xiàn)是經(jīng)過優(yōu)化的,用數(shù)字索引來訪問數(shù)組元素一般來說比訪問常規(guī)的對象屬性要快很多。
注意,可以使用負(fù)數(shù)或非整數(shù)來索引數(shù)組。這種情況下,數(shù)值轉(zhuǎn)換為字符串,字符串作為屬性名來用。
數(shù)組相關(guān)函數(shù) 數(shù)組遍歷方法for循環(huán)
Array.prototype.forEach()
forEach() 方法用于調(diào)用數(shù)組的每個元素,并將元素傳遞給回調(diào)函數(shù)。沒有返回值。
array.forEach(callback(currentValue[, index, array]]), [thisArg])
實例:遍歷并輸出所有數(shù)組元素
function logArrayElements(element, index, array) { console.log("a[" + index + "] = " + element); } // 注意索引 2 被跳過了,因為在數(shù)組的這個位置沒有項 [2, 5, , 9].forEach(logArrayElements); // logs: // a[0] = 2 // a[1] = 5 // a[3] = 9
Array.prototype.map()
map() 方法返回一個新數(shù)組,數(shù)組中的元素為原始數(shù)組元素調(diào)用函數(shù)處理后的值,不改變原數(shù)組。
var newArray = arr.map(callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg]);
實例1: 求數(shù)組中每個元素的平方根
var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); // roots的值為[1, 2, 3], numbers的值仍為[1, 4, 9]
實例2:在一個String上使用 map 方法獲取字符串中每個字符所對應(yīng)的 ASCII 碼組成的數(shù)組:
var map = Array.prototype.map var a = map.call("Hello World", function(x) { return x.charCodeAt(0); }) // a的值為[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
Array.prototype.filter()
filter()方法創(chuàng)建一個新數(shù)組,返回一個新的、由通過測試的元素組成的數(shù)組,如果沒有任何數(shù)組元素通過測試,則返回空數(shù)組。
var newArray = array.filter(callback(element[, index[, array]])[, thisArg])
實例:使用filter()創(chuàng)建具有非零id的元素的 json。
var arr = [ { id: 15 }, { id: -1 }, { id: 0 }, { id: 3 }, { id: 12.2 }, { }, { id: null }, { id: NaN }, { id: "undefined" } ]; // 判斷當(dāng)前元素是否為數(shù)字 function isNumber(obj) { return obj !== undefined && typeof(obj) === "number" && !isNaN(obj); } //callback過濾函數(shù) function filterByID(item) { if (isNumber(item.id) && item.id !== 0) { return true; } invalidEntries++; return false; } var arrByID = arr.filter(filterByID); // Filtered Array: // [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
Array.prototype.reduce()
方法對數(shù)組中的每個元素執(zhí)行一個由您提供的reducer函數(shù)(升序執(zhí)行),將其結(jié)果匯總為單個返回值。
語法:
var result = array.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
reduce為數(shù)組中的每一個元素依次執(zhí)行callback函數(shù),不包括數(shù)組中被刪除或從未被賦值的元素,接受四個參數(shù):
accumulator 累計器 currentValue 當(dāng)前值 currentIndex 當(dāng)前索引 array 數(shù)組
回調(diào)函數(shù)第一次執(zhí)行時,accumulator和currentValue的取值有幾種情況:
如果調(diào)用reduce()時提供了initialValue,accumulator取值為initialValue,currentValue取數(shù)組中的第一個值;
如果沒有提供initialValue,那么accumulator取數(shù)組中的第一個值,currentValue取數(shù)組中的第二個值。
如果數(shù)組為空且沒有提供initialValue,會拋出TypeError。
如果數(shù)組僅有一個元素(無論位置如何)并且沒有提供initialValue, 或者有提供initialValue但是數(shù)組為空,那么此唯一值將被返回并且callback不會被執(zhí)行。
reduce()如何運(yùn)行:
假如運(yùn)行下段reduce()代碼:
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){ return accumulator + currentValue; });
Callback 被調(diào)用四次,每次調(diào)用的參數(shù)和返回值如下表:
您還可以提供Arrow Function來代替完整的函數(shù)。 下面的代碼將產(chǎn)生與上面的代碼中相同的輸出:
[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr );
如果你打算提供一個初始值作為reduce()方法的第二個參數(shù),以下是運(yùn)行過程及結(jié)果:
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { returnaccumulator+ currentValue; }, 10); // =>20
實例1:計算數(shù)組中每個元素出現(xiàn)的次數(shù)
var names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"]; var names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"]; var countedNames = names.reduce(function (allNames, name) { if (name in allNames) { allNames[name]++; } else { allNames[name] = 1; } return allNames; }, {}); // countedNames is: // { "Alice": 2, "Bob": 1, "Tiff": 1, "Bruce": 1 }
實例2: 數(shù)組去重
let arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4]; let result = arr.sort().reduce(function(init, currentValue){ if(init.length === 0 || init[init.length - 1] !== currentValue){ init.push(current); } return init; }, []); // => [1, 2, 3, 4, 5]
此處額外附上其他數(shù)組去重方法以作對比參考
// 方法一 var norepeat = funtion(arr){ return arr.filter(function(val, index, array){ return array.indexOf(val) === index; }); } norepeat() // 方法二 var set = new Set(arr);
實例3:按順序運(yùn)行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) { return 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
Array.prototype.some()和Array.prototype.every()
some()方法測試是否至少有一個元素可以通過被提供的函數(shù)方法。該方法返回一個Boolean類型的值。some()被調(diào)用時不會改變數(shù)組。
array.some(callback(element[, index[, array]])[, thisArg])
實例:檢測在數(shù)組中是否有元素大于 10。
function isBiggerThan10(element, index, array) { return element > 10; } [2, 5, 8, 1, 4].some(isBiggerThan10); // false [12, 5, 8, 1, 4].some(isBiggerThan10); // true
every()方法就像數(shù)學(xué)中的“針對所有”的量詞,當(dāng)且僅當(dāng)針對數(shù)組中的所有元素調(diào)用判定函數(shù)都返回true,它才返回true。和some有相似之處。
實例:
a = [1,2,3,4,5]; a.every(function(x) { return X < 10; }) // => true:所有的值<10 a.every(function(x) { return x % 2 === 0; }) // => false: 不是所有的值都是偶數(shù)js數(shù)組方法
Array.prototype.push()和Array.prototype.pop():
push()方法向數(shù)組的末尾添加一個或更多元素,并返回新的長度。
pop()方法刪除并返回數(shù)組的最后一個元素。
Array.prototype.unshift()和Array.prototype.shift():
shift()方法刪除并返回數(shù)組的第一個元素。
unshift()方法向數(shù)組的頭部添加一個或更多元素,并返回新的長度。
注意,當(dāng)使用多個參數(shù)調(diào)用unshift()時它的行為令人驚訝。參數(shù)是一次性插入的(就像splice()方法)而非一次一個地插入。這意味著最終的數(shù)組中插入的元素的順序和它們在參數(shù)列表中的順序-致。而假如元素是一次一個地插入,它們的順序應(yīng)該是反過來的。
Array.prototype.reverse() :
方法將數(shù)組中元素的位置顛倒,并返回該數(shù)組。reverse()方法會改變原數(shù)組。
Array.prototype.sort() :
方法用原地算法對數(shù)組的元素進(jìn)行排序,并返回數(shù)組。排序算法現(xiàn)在是穩(wěn)定的。默認(rèn)排序順序是根據(jù)字符串Unicode碼點(diǎn)。由于它取決于具體實現(xiàn),因此無法保證排序的時間和空間復(fù)雜性。sort()原數(shù)組上原地排序,會導(dǎo)致原數(shù)組改變。
var a = [33, 4, 1111, 222]; a.sort(); //字母表順序: 1111,222,33,4 a.sort(function(a, b) { // =>a: [4, 33, 222, 1111] return a - b; // 根據(jù)順序,返回負(fù)數(shù)、0、正數(shù) }); a.sort( function(a, b) {return b - a}); // =>a: [1111, 222, 33, 4]
Array.prototype.concat(array2) :
方法用于合并兩個或多個數(shù)組。concat()方法不會更改原數(shù)組,而是返回一個新數(shù)組。
Array.prototype.join():
方法將數(shù)組中所有元素都轉(zhuǎn)化為字符串并連接在一起,返回最后生成的字符串。可以指定一個可選的字符串在生成的字符串中來分隔數(shù)組的各個元素。如果不指定分隔符,默認(rèn)使用逗號。join()方法不該變原數(shù)組。
實例:字符串?dāng)?shù)組連接成字符串
var arr = new Array(3) arr[0] = "George" arr[1] = "John" arr[2] = "Thomas" arr.join() // output: George,John,Thomas
Array.prototype.slice(start, end) :
slice()方法返回指定數(shù)組的一個片段或子數(shù)組。它的兩個參數(shù)分別指定了片段的開始和結(jié)束的位置。返回的數(shù)組包含第一個參數(shù)指定的位置和所有到但不含第二個參數(shù)指定的位置之間的所有數(shù)組元素。如果只指定一個參數(shù),返回的數(shù)組將包含從開始位置到數(shù)組結(jié)尾的所有元素。如參數(shù)中出現(xiàn)負(fù)數(shù),它表示相對于數(shù)組中最后一個元素的位置。slice()方法不會改變原數(shù)組。
// 語法: str.slice(beginSlice[, endSlice]) beginSlice: 必需。規(guī)定從何處開始選取。如果是負(fù)數(shù),那么它規(guī)定從數(shù)組尾部開始算起的位置。也就是說,-1 指最后一個元素,-2 指倒數(shù)第二個元素,以此類推。 endSlice: 可選。規(guī)定從何處結(jié)束選取。該參數(shù)是數(shù)組片斷結(jié)束處的數(shù)組下標(biāo)。如果沒有指定該參數(shù),那么切分的數(shù)組包含從 start 到數(shù)組結(jié)束的所有元素。如果這個參數(shù)是負(fù)數(shù),那么它規(guī)定的是從數(shù)組尾部開始算起的元素。 //實例: var arr = new Array(3) arr[0] = "George" arr[1] = "John" arr[2] = "Thomas" arr.slice(1) // output: John,Thomas
Array.prototype.splice() :方法通過刪除或替換現(xiàn)有元素或者原地添加新的元素來修改數(shù)組,并以數(shù)組形式返回被修改的內(nèi)容。此方法會改變原數(shù)組。
語法:
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
實例:
// 示例1: 添加元素 var fruits = ["Banana", "Orange", "Apple", "Mango"]; fruits.splice(2,1,"Lemon","Kiwi"); // output: Banana,Orange,Lemon,Kiwi,Mango // 示例2: 刪除元素 var fruits = ["Banana", "Orange", "Apple", "Mango"]; fruits.splice(2,2); // output: Banana,Orange
Array.prototype.indexOf()和Array.prototype.lastIndexOf():
index0f()和lastIndex0f()搜索整個數(shù)組中具有給定值的元素,返回找到的第一個元素的索引或者如果沒有找到就返回-1。index0f( )從頭至尾搜索,而lastIndexOf()則反向搜索。
Array.prototype.reduce(reducer):
方法對數(shù)組中的每個元素執(zhí)行一個由您提供的reducer函數(shù)(升序執(zhí)行),將其結(jié)果匯總為單個返回值。
Array.prototype.map():對數(shù)組的每一項應(yīng)用回調(diào)函數(shù),返回新數(shù)組。
Array.prototype.some():數(shù)組中只需有一項滿足給定條件則返回true。
Array.prototype.every():數(shù)組的每一項都滿足給定條件則返回true。
Array.prototype.filter():方法創(chuàng)建一個新數(shù)組, 其包含通過所提供函數(shù)實現(xiàn)的測試的所有元素。
Array.prototype.forEach():數(shù)組遍歷,與for循環(huán)一樣,沒有返回值。
數(shù)組類型給定一個未知的對象,判定它是否為數(shù)組通常非常有用。在ECMAScript 5中,可以使用Array.isArray()函數(shù)來做這件事情:
Array.isArray([]) //=>true Array.isArray({}) // => false
在ECMAScript 3中isArray( )函數(shù)的代碼可以這樣書寫:
var isArray = Function.isArray || function(o) { return typeof o === "object" && Object.prototype.toString. call(o) === "[object Array]"; };類數(shù)組對象
我們已經(jīng)看到,JavaScript數(shù)組的有- - 些特性是其他對象所沒有的:
* 當(dāng)有新的元素添加到列表中時,自動更新length屬性。 * 設(shè)置length為一個較小值將截斷數(shù)組。 * 從Array.prototype中繼承一些有用的方法。 * 其類屬性為“Array" 。
這些特性讓JavaScript數(shù)組和常規(guī)的對象有明顯的區(qū)別。但是它們不是定義數(shù)組的本質(zhì)特性。一種常常完全合理的看法把擁有-個數(shù)值length屬性和對應(yīng)非負(fù)整數(shù)屬性的對象看做一種類型的數(shù)組。
實例:為一個常規(guī)對象增加了一些屬性使其變成類數(shù)組對象,然后遍歷生成的偽數(shù)組的“元素”:
var a = {}; // 從一個常規(guī)空對象開始 // 添加一些屬性,稱為"類數(shù)組" var i = 0; while(i < 10) { a[i] = i * i; i++; } a.length = i; // 現(xiàn)在,當(dāng)做真正的數(shù)組遍歷它 var total = 0; for(var j = 0; j < a.length; j++) total += a[j] ; // => 287
JavaScript中的Arguments對象就是一個類數(shù)組對象。一些DOM方法(如document.getElementsByTagName()也返回類數(shù)組對象。
下面有一個函數(shù)可以用來檢測類數(shù)組對象:
//判定o是否是一個類數(shù)組對象 //字符串和函數(shù)有l(wèi)ength屬性,但是它們 //可以用typeof檢測將其排除。在客戶端JavaScript中,DOM文 本節(jié)點(diǎn) //也有l(wèi)ength屬性,需要用額外判斷o. nodeType != 3將其排除 function isArrayLike(o) { return o && typeof o === "object" && isFinite(o.length) && o.length >= 0 && o.length === Math.floor(o.length) && o.length < 4294967296; }
參考:
* 《JavaScript權(quán)威指南》第六版 * [MDN Web 文檔](https://developer.mozilla.org/zh-CN/)
推薦閱讀:
【專題:JavaScript進(jìn)階之路】
JavaScript之“use strict”
JavaScript之new運(yùn)算符
JavaScript之call()理解
JavaScript之對象屬性
我是Cloudy,年輕的前端攻城獅一枚,愛專研,愛技術(shù),愛分享。
個人筆記,整理不易,感謝閱讀、點(diǎn)贊和收藏。
文章有任何問題歡迎大家指出,也歡迎大家一起交流前端各種問題!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/105431.html
摘要:專題系列共計篇,主要研究日常開發(fā)中一些功能點(diǎn)的實現(xiàn),比如防抖節(jié)流去重類型判斷拷貝最值扁平柯里遞歸亂序排序等,特點(diǎn)是研究專題之函數(shù)組合專題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實現(xiàn)模式需求我們需要寫一個函數(shù),輸入,返回。 JavaScript 專題之從零實現(xiàn) jQuery 的 extend JavaScritp 專題系列第七篇,講解如何從零實現(xiàn)一個 jQuery 的 ext...
摘要:將元素作為對象的鍵,默認(rèn)鍵對應(yīng)的值為如果對象中沒有這個鍵,則將這個元素放入結(jié)果數(shù)組中去。 前言 數(shù)組去重在日常開發(fā)中的使用頻率還是較高的,也是網(wǎng)上隨便一抓一大把的話題,所以,我寫這篇文章目的在于歸納和總結(jié),既然很多人都在提的數(shù)組去重,自己到底了解多少呢。又或者是如果自己在開發(fā)中遇到了去重的需求,自己能想到更好的解決方案嗎。 這次我們來理一理怎么做數(shù)組去重才能做得最合適,既要考慮兼容性,...
摘要:對象數(shù)組初始化表達(dá)式,闖關(guān)記之上文檔對象模型是針對和文檔的一個。闖關(guān)記之?dāng)?shù)組數(shù)組是值的有序集合。數(shù)組是動態(tài)的,根闖關(guān)記之語法的語法大量借鑒了及其他類語言如和的語法。 《JavaScript 闖關(guān)記》之 DOM(下) Element 類型 除了 Document 類型之外,Element 類型就要算是 Web 編程中最常用的類型了。Element 類型用于表現(xiàn) XML 或 HTML 元素...
摘要:寫在前面專題系列是我寫的第二個系列,第一個系列是深入系列。專題系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點(diǎn)贊,鼓勵指正。 寫在前面 JavaScript 專題系列是我寫的第二個系列,第一個系列是 JavaScript 深入系列。 JavaScript 專題系列共計 20 篇,主要研究日常開發(fā)中一些功能點(diǎn)的實現(xiàn),比如防抖、節(jié)流、去重、類型判斷、拷貝、最值、扁平、柯里...
摘要:數(shù)組一數(shù)組是什么是值得有序集合,每個元素都在數(shù)組里有唯一的位置,用數(shù)字表示,叫做索引數(shù)據(jù)用字符串表示,叫關(guān)聯(lián)數(shù)組。 JS(JavaScript) 數(shù)組; 一.數(shù)組是什么; 是值得有序集合,每個元素都在數(shù)組里有唯一的位置,用數(shù)字表示,叫做索引數(shù)據(jù);用字符串表示,叫關(guān)聯(lián)數(shù)組。數(shù)組無類型;數(shù)組元素可以是類型,字符串,數(shù)字值,布爾值等數(shù)組動態(tài)的;向插入新元素,從數(shù)組中刪除指定元素 二.一維數(shù)組...
閱讀 3503·2021-11-24 09:39
閱讀 780·2019-08-30 14:22
閱讀 3031·2019-08-30 13:13
閱讀 2310·2019-08-29 17:06
閱讀 2918·2019-08-29 16:22
閱讀 1255·2019-08-29 10:58
閱讀 2427·2019-08-26 13:47
閱讀 1627·2019-08-26 11:39