在JavaScript中,数组可以使用Array构造函数来创建,或使用[]快速创建,这也是首选的方法。数组是继承自Object的原型,并且他对typeof没有特殊的返回值,他只返回'object'。

运行[] instanceof Array他会返回ture。虽然结果是这样,但也有复杂的类数组对象,如字符串或arguments对象,但arguments对象并非是Array的实例,但他却拥有length属性,而且他的值是可以被索引的,因此他可以像一个数组那样被遍历。

这本文中,我将介绍数组原型的一些方法,并探讨每一种方法的用途:
使用.forEach 来做遍历 
使用.some and .every 来断言
使用 .join and .concat 来合并
使用 .pop, .push, .shift, and .unshift 来操作栈和队列
使用 .map 映射模型
使用 .filter 来做查询
使用 .sort 来做排序
使用 .reduce, .reduceRight 来计算
使用 .slice 来复制
.splice 的用途
使用 .indexOf 来查找
in 操作符介绍
.reverse 的用途

使用 .forEach来遍历
======
这是原生Javascript数组最简单的方法之一,但他不支持IE6~8。

forEach 会在遍历数组中的每个元素时就执行一次回调函数,并传递三个参数。
value 当前的数组元素
index 当前元素在数组中的位置
array 对数组的引用

此外,我们还可以传递一个可选的参数,作为每个函数调用时的上下文(this),看下面例子:

['_', 't', 'a', 'n', 'i', 'f', ']'].forEach(function (value, index, array) {
this.push(String.fromCharCode(value.charCodeAt() + index + 2))
}, out = []) out.join('')
// <- 'awesome'

这里使用了.join,这是我们还没有提及到的,但往后我们会再作介绍,在这个例子中,他可以连接数组中的不同元素,可以达到类似字符串拼接的效果。out[0] + '' + out[1] + '' + out[2] + '' + out[n].

我们不能中止forEach循环和抛出异常,在这些情景下,我们可以选择使用其他可用的方法。

使用 .some和.every来断言
=====

如果你曾使用过.Net的 enumerables,也许你熟悉.Any(x => x.IsAwesome) and .All(x => x.IsAwesome).
这些方法和.forEach非常相似,他们同样地给回调函数传递了value, index 和array, 你也同样的可以给他传入二个可选参数来作为回调函数的上下文。MDN是这样来描述.some的:

".some方法可以在遍历数组中的每个元素时执行回调函数,直到回调函数返回true为止,如果这个元素被发现,.some立即返回true。否则.some会返回false. 回调函数只对数组非空元素的索引调用,并不会对已经被删除或从未被指派的值调用"

max = -Infinity
satisfied = [10, 12, 10, 8, 5, 23].some(function (value, index, array) {
if (value > max) max = value
return value < 10
}) console.log(max)
// <- 12 satisfied
// <- true

回调函数会在满足条件value < 10时停止执行。.every也是同样的道理,但他的短路是发生在回调函数返回false时。

使用 .join and .concat 来合并
=====
.join方法通常会和.concat方法混淆。.join是创建一个通过分隔符来链接数组中各元素的字符串,如果不提供分隔符,他就会默认以逗号作用分隔符。.concat通过他的源数组创建一个新的数组。

.concat 可以传入多个参数: array.concat(val, val2, val3, valn)
.concat 是可以返回一个新的数组
array.concat() 如果不传入参数则将会返回一个新的浅拷贝数组。

浅拷贝意味着副本可以保存着源数组的对象引用。例如:

var a = { foo: 'bar' }
var b = [1, 2, 3, a]
var c = b.concat() console.log(b === c)
// <- false b[3] === a && c[3] === a
// <- true

使用 .pop, .push, .shift, and .unshift 来操作栈和队列
===
现在大家都知道可以通过.push方法来往数组中添加元素,但你是否知道.push可以传入多个参数,一次性把多个参数添加到数组后面。如:[].push('a', 'b', 'c', 'd', 'z')

.pop方法和.push方法刚好相反。他将会返回数组中的最后一个元素,并且同时从数组中删除这个元素。如果数组为空,则会返回void . (undefined)。使用.push和.pop,我可以非常容易地创建一个LIFO(last in first out) 的栈。

function Stack () {
this._stack = []
} Stack.prototype.next = function () {
return this._stack.pop()
} Stack.prototype.add = function () {
return this._stack.push.apply(this._stack, arguments)
} stack = new Stack()
stack.add(1,2,3) stack.next()
// <- 3

反之,我可以通过使用.unshift 和.shift来创建一个FIFO(fist in first out) 的队列。

function Queue () {
this._queue = []
} Queue.prototype.next = function () {
return this._queue.shift()
} Queue.prototype.add = function () {
return this._queue.unshift.apply(this._queue, arguments)
} queue = new Queue()
queue.add(1,2,3) queue.next()
// <- 1

使用.shift (或.pop) 可以容易地遍历数组。

list = [1,2,3,4,5,6,7,8,9,10]

while (item = list.shift()) {
console.log(item)
} list
// <- []

使用 .map 映射模型
=========
.map在遍历数组中的每个元素时执行一次回调函数,并且会返回一个新的数组。回调函数只会对数组的元素索引执行,并不会对已删除或没元素的索引而执行。

Array.prototype.map方法和.forEach,.some和.every有着相似的地方:.map(fn(value, index, array), thisArgument)。

values = [void 0, null, false, '']
values[7] = void 0
result = values.map(function(value, index, array){
console.log(value)
return value
}) // <- [undefined, null, false, '', undefined × 3, undefined]

undefined × 3 的意思是.map不会在一个删除或者未定义的数组元素上执行,但他们会继续保留在结果数组上。映射是对数组的转化是非常有用的。看下面示例:

// casting
[1, '2', '30', '9'].map(function (value) {
return parseInt(value, 10)
})
// 1, 2, 30, 9 [97, 119, 101, 115, 111, 109, 101].map(String.fromCharCode).join('')
// <- 'awesome' // a commonly used pattern is mapping to new objects
items.map(function (item) {
return {
id: item.id,
name: computeName(item)
}
})

使用 .filter 来做查询
======

.filter在遍历数组中的每个元素时执行一次回调函数,并且回调函数返回的true时,他将会保存这当前元素,最后返回一个新数组。回调函数只会对数组的元素索引执行,并不会对已删除或没元素的索引而执行。不传递到回调函数的元素将会被简单的忽略,并且不会在新的数组中出现。

[void 0, null, false, '', 1].filter(function (value) {
return value
})
// <- [1] [void 0, null, false, '', 1].filter(function (value) {
return !value
})
// <- [void 0, null, false, '']

使用.sort 来做排序
========

如果不提供回调函数,元素将会通过转换为字符后并且按照在字典中的顺序来排序。例如在字典中"80"在"9"的前面,但如果按数字来排序,则9在80之前。

就像大多数的排序函数一样,Array.prototype.sort(fn(a,b))可以比较两个元素。并且会在以下三个情况中返回值。

如果 a 应该出现在 b 之前,则返回值小于0。
如果a 和b 相等,则返回0。
如果 a 应该出现在 b 之后,刚返回值大于0。

[9,80,3,10,5,6].sort()
// <- [10, 3, 5, 6, 80, 9] [9,80,3,10,5,6].sort(function (a, b) {
return a - b
})
// <- [3, 5, 6, 9, 10, 80]

使用 .reduce, .reduceRight 来计算
========
这两个方法都有着同样的特性:
.reduce(callback(previousValue, currentValue, index, array), initialValue).
在每一个回调函数执行时,previousValue将会被返回。初始化时initialValue将会被传入回调函数,currentValue包含着当前的元素,index表示该元素的在数组中的位置。array为数组的引用。
一个经典的.reduce例子就是加法函数。

Array.prototype.sum = function () {
return this.reduce(function (partial, value) {
console.log(partial, ",",value)
return partial + value
}, 0)
}; [3,4,5,6,10].sum()
// <- 28

如果说我们要合并一些字符串,我们可能会用到.join方法来达到目的。但是在下面这个例子中,.join方法就可能达不到我们的要求了,除非这些对象都有valueOf或者toString属性。但我们可以使用.reduce方法来轻松实现合并各对象为字符串。

function concat (input) {
return input.reduce(function (partial, value) {
if (partial) {
partial += ', '
}
return partial + value.name
}, '')
} concat([
{ name: 'George' },
{ name: 'Sam' },
{ name: 'Pear' }
])

注:reduce和reduceRight的区别是,reduce 是从数组左到右开始遍历,而reduceRight是从数组右到左开始遍历。

使用 .slice 来复制
======
Array.prototype.slice can be used to convert array-like objects into real arrays.
和.concat相似,可以通过不传递参数给.slice方法来复制源数组。.slice方法可以传入两个参数,一个是开始位置,另一个是结束位置。Array.prototype.slice也可以把类数组转为数组。

Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 })
// <- ['a', 'b']

但是用.concat就达不到这样的目的了,因为他会把类数组放到一个真正的数组中。

Array.prototype.concat.call({ 0: 'a', 1: 'b', length: 2 })
// <- [{ 0: 'a', 1: 'b', length: 2 }]

除此之外,我们还可以把类数组转换为真正的数组之后,并且去除数组前面几个元素。

function format (text, bold) {
if (bold) {
text = '<b>' + text + '</b>'
}
var values = Array.prototype.slice.call(arguments, 2) values.forEach(function (value) {
text = text.replace('%s', value)
}) return text
} format('some%sthing%s %s', true, 'some', 'other', 'things')
// <- <b>somesomethingother things</b>

.splice 的用途
====
.splice也是一个常用的数组方法。你可以通过.splice来删除元素,插入新元素,并且可以调用一次.splice在同样的位置达到删除,插入元素的目标不。要注意的是,这个方法是会改变源数组。

var source = [1,2,3,8,8,8,8,8,9,10,11,12,13]
var spliced = source.splice(3, 4, 4, 5, 6, 7) console.log(source)
// <- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13] spliced
// <- [8, 8, 8, 8]

如果你有留意,他会返回已删除的元素。

var source = [1,2,3,8,8,8,8,8,9,10,11,12,13]
var spliced = source.splice(9) spliced.forEach(function (value) {
console.log('removed', value)
})
// <- removed 10
// <- removed 11
// <- removed 12
// <- removed 13 console.log(source)
// <- [1, 2, 3, 8, 8, 8, 8, 8, 9]

使用 .indexOf 来查找
=========
通过使用.indexOf方法,我们可以找到元素在数组中的位置。如果找不到,将会返回-1。如果要查找,通常我会这样写比较a === 'a' || a === 'b' || a === 'c',但在这个场景,你可以['a', 'b', 'c'].indexOf(a) !== -1。

要注意的是,如果是查找数组中的对象,那么你要提供相同的对象引用。第二个参数是表示从数组中的哪个位置开始搜索。

var a = { foo: 'bar' }
var b = [a, 2] console.log(b.indexOf(1))
// <- -1 console.log(b.indexOf({ foo: 'bar' }))
// <- -1 console.log(b.indexOf(a))
// <- 0 console.log(b.indexOf(a, 1))
// <- -1 b.indexOf(2, 1)
// <- 1

如果你希望反顺序查找,你可以使用.lastIndexOf。

in 操作符介绍
========
.indexOf 和 in操作符非常容易混淆。

var a = [1, 2, 5]

1 in a
// <- true, but because of the 2! 5 in a
// <- false

问题就在这里,in操作符是用于检查一个对象的键,而不是查找一个元素在数组中的位置。当然这比.indexOf快。

var a = [3, 7, 6]

1 in a === !!a[1]
// <- true

in操作符相乎是把传递进来的值转换为布尔值。!!表达式是可以把值隐式转换为布尔值。

关于.reverse
=========
这个方法是可以把数组中的元素位置反转。

var a = [1, 1, 7, 8]

a.reverse()
// [8, 7, 1, 1]

这里并非返回一个副本,而是直接修改了数组的本身。

javascript中数组常用的方法的更多相关文章

  1. javascript中数组常用的方法和属性

    前言 在javascript中,数组是一种非常重要的数据类型,我们时常会和它打交道,最近在开发项目中频繁的使用到数组,但是自己对数组的众多方法已经是非常模糊了,为了方便自己以后能够更好的使用数组中的属 ...

  2. javascript中数组Array的方法

    一.常用方法(push,pop,unshift,shift,join)push pop栈方法,后进先出var a =[1,2,3];console.log(a.push(40)); //4 返回数组的 ...

  3. Javascript中数组的判断方法

    摘要: 1.数组检测的方法: 1) typeof . 2) instanceof . 3) constructor . 4) Object.prototype.toString. 5) Array.i ...

  4. javascript中最常用的方法

    平时在工作中时常需要一些方法,下面列举几个最常用的几个方法. 1. indexOf(searchvalue,fromindex) 该方法用于查找一个字符串是否包含了另一个字符串 indexOf() 方 ...

  5. JS 开发中数组常用的方法

    大家有没有想过,js数组为什么会有这么多的方法,没错,就是为了不同场景下处理数据的需要,就像设计模式一样,都是为了能更好的处理当前场景的需要. 首先怎么创建一个数组呢, // 两种方式 // 1,构造 ...

  6. javascript中array常用属性方法

    属性: length 表示一个无符号 32-bit 整数,返回一个数组中的元素个数. 截短数组..截短至长度2  则:   .length = 2 方法: Array.from() 方法可以将一个类数 ...

  7. javascript中数组的concat()方法 - 数组连接

    <html> <head> <title>数组的concat()方法</title> <script> /* 数组的concat()方法: ...

  8. 【前端_js】javascript中数组的map()方法

    数组的map()方法用于遍历数组,每遍历一个元素就调用回调方法一次,并将回调函数的返回结果作为新数组的元素,被遍历的数组不会被改变. 语法:let newAarray = arr.map(functi ...

  9. 一张图看懂JavaScript中数组的迭代方法:forEach、map、filter、reduce、every、some

    好吧,竟然不能单发一张图,不够200字啊不够200字! 在<JavaScript高级程序设计>中,分门别类介绍了非常多数组方法,其中迭代方法里面有6种,这6种方法在实际项目有着非常广泛的作 ...

随机推荐

  1. 猿题库 iOS 客户端架构设计-唐巧

    序 猿题库是一个拥有数千万用户的创业公司,从20013年题库项目起步到2015年,团队保持了极高的生产效率,使我们的产品完成了五个大版本和数十个小版本的高速迭代. 在如此快速的开发过程中,如何保证代码 ...

  2. 关于scrollWidth,clientWidth,offsetWidth

    scrollWidth:对象的实际内容的宽度,不包含边线(border)的宽度,会随对象的内容可视区后而变大. scrollHeight:对象的实际内容的高度,不包含边线(border)的宽度,会随对 ...

  3. vi/vim

    config file location 1. MinGW: C:\MinGW\msys\1.0\share\vim\vimrc 2. Linux: home config file content ...

  4. PSVR开发者需要了解的9件事

    1 首先需要了解下PSVR的具体硬件参数:整个产品都包括哪些: 2 如何创造更好的 VR 内容 三种准备:设计.内容.技术 针对PSVR设计:体验范围.跟踪限制.社交屏幕 VR应用和内容:模拟.沟通. ...

  5. POJ - 1132Border

    POJ - 1132Border Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d & %I64u Descrip ...

  6. oracle触发器及异常处理 简单例子

    create sequence person_seq start with 1 increment by 1 order                     --按顺序 nocycle       ...

  7. phpcms V9 MVC模式 与 URL访问解析

    [1]URL访问解析 观察访问网页时的网址,可以得出模块访问方法,如下示例: http://www.abcd.com.cn/phpcms/index.php?m=content&c=index ...

  8. TextBox

    一.聚焦: private void FrmOnlineChargeMoney_Paint(object sender, PaintEventArgs e) { edtAuthCode.SelectA ...

  9. 使用Android studio 出现的问题解决

    问题一.安装过程中出现的报错Failed to install Intel HAXM 解决:重启电脑,启动BIOS,我的是惠普的,开机时按F10就进去了 切换到Configuration选项,将设置I ...

  10. JQ的live(),on(),deletage(),bind()几个的区别

    今天在网上看到一篇文章,关于JQ里面事件绑定的区别,说说我自己看后的理解,本人菜鸟一枚,很多东西不懂 ,有理解错误的还望大神们多多指教 bind()方法是绑定事件最直接的方法,这个方法是绑定到docu ...