javascript中数组常用的方法

在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]

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

时间: 2024-10-12 16:08:33

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

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

前言 在javascript中,数组是一种非常重要的数据类型,我们时常会和它打交道,最近在开发项目中频繁的使用到数组,但是自己对数组的众多方法已经是非常模糊了,为了方便自己以后能够更好的使用数组中的属性和方法,在此记录一下. 数组常用的属性和方法 常用属性 Array.length:返回数组的大小 常用方法 Array.pop():删除并返回数组的最后一个元素 Array.push():向数组的结尾添加元素 Array.shift():将元素移除数组 Array.unshift():向数组头部添

javascript中数组比较大小方法

javascript中数组取最大值和最小值 1.排序法 我们给数组进行排序,可以按照从小到大的顺序来排,排序之后的数组中第一个和最后一个就是我们想要获取的最小值和最大值.排序我们会用到数组的 sort 方法. var arr = [12,56,25,5,82,51,22]; arr.sort(function (a, b) { return a-b; }); // [5,12,22,25,51,56] var min = arr[0]; // 5 var max = arr[arr.length

Javascript中数组的判断方法

摘要: 1.数组检测的方法: 1) typeof . 2) instanceof . 3) constructor . 4) Object.prototype.toString. 5) Array.isArray(). 以上为数组检测的方法,但是这些方法中: Array.isArray()方法是最为简单方便的方法,但是存在版本支持性问题,没有版本支持性问题且较好的检测方法是使用Object.prototype.toString结合call()方法来检查,通常数组检测中我们常用的做法是两种方法结合

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

1 <html> 2 <head> 3 <title>数组的concat()方法</title> 4 5 <script> 6 /* 7 数组的concat()方法: 8 1.该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本. 9 2.返回一个新的数组.该数组是通过把所有 arrayX 参数添加到 arrayObject 中生成的. 10 如果要进行 concat() 操作的参数是数组,那么添加的是数组中的元素,而不是数组. 11 */

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

数组的map()方法用于遍历数组,每遍历一个元素就调用回调方法一次,并将回调函数的返回结果作为新数组的元素,被遍历的数组不会被改变. 语法:let newAarray = arr.map(function callback(currentValue, index, array) { // Return element for newArray } 示例: let numbers = [1, 5, 10, 15]; let doubles = numbers.map((x) => { return

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

好吧,竟然不能单发一张图,不够200字啊不够200字! 在<JavaScript高级程序设计>中,分门别类介绍了非常多数组方法,其中迭代方法里面有6种,这6种方法在实际项目有着非常广泛的作用.其中本人最爱用forEach和map,好用又高效,不用什么都是for循环大法.但是初学的时候往往觉得头大,这些方法都很像,到底有什么区别?趁着今天有空,我把对着6个方法的认知,用最浅显的图画出来,希望看到的同学觉得有用.

javascript中数组的map方法

map方法原型:array1.map(callbackfn[, thisArg]) 参数: array1,必选. 一个数组对象.该函数一般用于数组对象 callbackfn,必选. 最多可以接受三个参数的函数. 对于数组中的每个元素,map 方法都会调用 callbackfn 函数一次. thisArg,可选. callbackfn 函数中的 this 关键字可引用的对象. 如果省略 thisArg,则 undefined 将用作 this 值. 返回值: 一个新数组,其中的每个元素均为关联的原

javaScript中 数组的新方法(reduce)

定义和用法 reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值. reduce() 可以作为一个高阶函数,用于函数的 compose. 注意: reduce() 对于空数组是不会执行回调函数的. 浏览器支持 表格中的数字表示支持该方法的第一个浏览器版本号. 语法 :array.reduce(function(total, currentValue, currentIndex, arr), initialValue) 参数 栗子1: var arr

javascript中数组元素删除方法splice,用在for循环中巨坑

一.demo splice: 该方法会改变自动原始数组长度 实例: var array = ["aa","dd","cc","aa"]; //方法2:删除数组元素 array.splice(1,1); //输出结果:["aa","cc","aa"] getArray(array); 输出:aa cc aa 数组长度自动减一 二.实际业务场景中 在for循环中使y用 t