在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. 中兴F412光猫超级密码破解、破解用户限制、关闭远程控制、恢复路由器拨号

    不少家庭都改了光纤入户,那肯定少不了光猫的吧.今天以中兴F412光猫为例介绍下此型号光猫超级密码的破解方法.一.F412超级密码破解方法1.运行CMD,输入telnet 192.168.1.1: 2. ...

  2. SVD奇异值分解

    奇异值分解 备忘:Eigen类库可能会和其他库产生冲突,将Eigen类库的头文件引用放到前面解决了.

  3. Struts2(六):ResultType

    本章节将继续学习struts2的返回类型的使用方法. 学习文档下载struts2 full包解压后会在doc下包含离线html文档. 点击运行后页面: 点击Guides向导终将会有向导列表 再点开后, ...

  4. Number类型方法

    //1.toString();  转换成字符串 var s=123; console.log(typeof s.toString()); //string //2.toLocaleString()   ...

  5. Java语言的编写规范

    ,区别大小写.2,注意编程格式,比如对齐啊 什么的.3,注释一定要写好,有统一的// 或者/* */,这样让程序好看.4,定义变量的时候竟让别人看明白,不要A 啊B 啊什么的 要用英语单词这类的,简而 ...

  6. html5,新增的元素,fieldset legend

    <form action="">    <fieldset>        <legend>用户注册</legend>       ...

  7. OBD K线抓包

    14230 Link 命令:  const u8 LinkCmd14230[6] = { 0xC2, 0x33, 0xF1, 0x01, 0x00, 0xE7 }; 14230 Enter 命令: c ...

  8. php之XML转数组函数的方法

    <?/** * xml2array() will convert the given XML text to an array in the XML structure. * Link: htt ...

  9. js 操作 字符串

    去w3school看看string的基本方法把: 方法描述 anchor()    创建 HTML 锚.    big()    用大号字体显示字符串.    blink()    显示闪动字符串.  ...

  10. Poj(1251),Prim字符的最小生成树

    题目链接:http://poj.org/problem?id=1251 字符用%s好了,方便一点. #include <stdio.h> #include <string.h> ...