javascript 数组操作方法归纳总结
文内的部分目录结构参考了《JavaScript高级程序设计(第3版)》,文内描述来个不同的书籍、文章以及自己的测试示例。
remark: 一下测试用例均在Chrome浏览器控制台内测试。
转换方法
javascript内的所有数据类型都有这三个方法:toString(), valueOf(), toLocaleString()。
1. toString()
数组的toString()方法会返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。
var arr = [1, 2, 3]; console.log(arr.toString()); // "1,2,3" alert(arr); // "1,2,3"
2. valueOf()
valueOf()方法返回的值可以视为调用方法的本身。(“JS中令人发指的valueOf方法”这篇文章做了深入的了解,有兴趣的可以阅读)
var arr = [1, 2, 3, 4, 5]; arr.valueOf(); // [1, 2, 3, 4, 5] typeof arr.valueOf(); // "object" arr instanceof Array; // true Array.isArray(arr.valueOf()); // true console.log(arr.valueOf()); // "1,2,3,4,5" // 其他类型 var str = "string.value"; str.valueOf(); // "string.value" var num = 10; num.valueOf(); // 10 var bool = true; bool.valueOf(); // true var obj = { a: "a" }; obj.valueOf(); // Object {a: "a"} var func = function () {}; func.valueOf(); // function (){} var _null = null; _null.valueOf(); // TypeError:Cannot read property 'valueOf' of null var _undefined = undefined; _undefined.valueOf(); // TypeError:Cannot read property 'valueOf' of null
3.toLocaleString()
数组的toLocaleString()方法也是将数组转换成字符串输出,输出结果和toString()相同。但与toString()方法的不同之处在于:它是使用数组每个元素的toLocaleString()方法转换成字符串之后已形成以逗号为分隔的字符串。
var arr = [1, 2, 3, 4, 5]; arr.toLocaleString(); // "1,2,3,4,5" // 这段代码看起来不明显,感觉和toString()方法是一样的 // 下面引用高设3中的一段代码来提现toLocaleString()的内幕 var person1 = { toLocaleString: function () { return "Nikolaos"; } , toString: function () { return "Nicholas"; } }; var person2 = { toLocaleString: function () { return "Grigorios"; } , toString: function () { return "Greg"; } }; var people = [person1, person2]; console.log(people.toString()); // "Nicholas,Greg" console.log(people.toLocaleString()); // "Nikolaos,Grigorios"
4.join()
数组的join()方法可以使用不同的分隔符连接数组元素形成字符串。join()方法只接受一个参数,即为组成字符串的分隔符。
remark: 如果不给join()方法传入任何参数,或给它传入undefined,则使用逗号作为分隔符。IE7及更早的版本会错误的使用字符串"undefined"作为分隔符。如果数组中某一项是null或undefined,以上四个方法在返回结果中均以空字符串表示。
var arr = [1, 2, 3, 4, 5]; arr.join(); // "1,2,3,4,5" arr.join("|"); // "1|2|3|4|5" arr.join("%"); // "1%2%3%4%5" arr.join("1"); // "112131415" arr.join("undefined"); // "1undefined2undefined3undefined4undefined5" arr.join(undefined); // "1,2,3,4,5" arr.join(null); // "1null2null3null4null5"
栈方法:push()和pop()
栈是一种LIFO(Last-In-First-Out,后进先出)的数据结构,也就是最新添加的项最早被移出。而栈中项的插入(叫做推入)和移除(叫做弹出),只发生在一个位置--栈的顶部。ECMAScript维数组提供了push()和pop()方法,以便实现类似栈的行为。
push()方法可以接受任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。
pop()方法从数组末尾移除最后一项,减少数组的length长度,然后返回移除的项。
var arr = []; arr.push("0", "1"); // 返回数组长度为:2 arr.push("2"); // 返回数组长度为:3 arr.pop(); // 返回移除的项:"2" arr.length; // 数组长度为:2 arr = new Array(); arr.push("black"); // 返回数组长度:1 arr.push("blue"); // 返回数组长度:2 arr[2] = "green"; arr.pop(); // 返回移除项:"green" arr.length; // 数组长度为:2
队列方法:shift()
队列是一种先进先出FIFO(First-In-First-Out)的数据结构,在列表的末端添加项,在列表的前端移除项。push()方法结合shift()方法可以模拟队列行为。
shift()方法用于移除数组中的第一项并返回该项,同时将数组长度减1。
var arr = new Array(); arr.push("black", "white"); // 数组长度为:2 arr.push("blue"); // 数组长度为:3 arr.shift(); // 移除并返回:"black" arr.length; // 数组长度为:2
shift()方法与pop()方法相对应,一个从数组顶部移除项,一个从数组末尾移除项。而push()是从数组末尾添加项,ECMAScript也提供了一个与之相对应从数组顶部添加项并返回数组长度的方法:unshift()方法。
var arr = new Array(); arr.unshift("red"); // 可以自己往unshift()方法里面传入多个参数,看看与自己想想的结果是否一样 // 返回数组长度:1 arr.unshift("black"); // 返回数组长度:2 arr.unshift("white"); // 返回数组长度:3 arr.unshift("blue"); // 返回数组长度:4 arr.shift(); // 返回顶部移除项:"blue",数组长度变更为:3 arr.pop(); // 返回末尾移除项:"red",数组长度变更为:2
重排方法:reverse()和sort()
1. reverse()
reverse()方法把数组内元素按现有排序进行反序排序。
var arr = [3, 5, 2, 1, 4]; arr.reverse(); console.log(arr); // [4, 1, 2, 5, 3]
2. sort()
相较于reverse()方法的简单实用,sort()方法的使用略显多样。
在默认情况下,sort()方法按升序排序数组项——即最小的值位于最前面,最大的值位于最后面。为了实现排序,sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串,以确定如何排序。
请看如下一组数字组合的排序,是否能够按数字大小达到期望排序结构呢?
var arr = [2, 10, 1, 5, 30, 100, 90]; arr.sort(); // 排序结果是否是:[1, 2, 5, 10, 30, 90, 100] ? // 显然不是 // 最后的结果是:[1, 10, 100, 2, 30, 5, 90]
最后的结果显然不是按数字大小进行排序,原因是:数组内的数字会先调用其本身的toString()方法转换成字符串,再进行排序。
要上面上面的问题,就要提到sort()的另一种方式,以函数为其参数。
function compare(value1, value2) { if (value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } } var arr = [2, 10, 1, 5, 30, 100, 90]; arr.sort(compare); // [1, 2, 5, 10, 30, 90, 100]
操作方法
1. concat()
concat()方法可以基于当前数组中的所有项创建一个新数组。具体说来,这个方法会先创建一个当前数组的副本,让后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。在没有给concat()方法传递参数的情况下,它只是复制当前数组并返回副本。如果传递给concat()方法一个或多个数组,则该方法将这些数组中的每一项都添加到结果数组中。如果传递的参数不是数组,这些值会被简单的添加到结果数组的末尾。concat()方法不影响原始数组。
var arr = ["red", "green", "blue"]; var arr2 = arr.concat("yellow", ["black", "white"]); console.log(arr); // ["red", "green", "blue"] console.log(arr2); // ["red", "green", "blue", "yellow", "black", "white"]
2. slice()
slice()方法能够基于当前数组中的一个或多个项创建一个新数组。slice()方法接受一个或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下,slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。slice()方法不会影响原始数组。
var arr = ["red", "green", "blue", "black", "white"]; var arr2 = arr.slice(1); var arr3 = arr.slice(1, 4); console.log(arr); // ["red", "green", "blue", "black", "white"] console.log(arr2); // ["green", "blue", "black", "white"] console.log(arr3); // ["green", "blue", "black"]
3. splice()
splice()的主要用途是向数组的中部插入项,使用方式有如下三种:
(1) 删除:可以删除任意数量的项,需要指定两个参数:splice(要删除的第一项的位置, 要删除的项数);
(2) 插入:可以向指定位置插入任意数量的项,最少需要三个参数:splice(起始位置, 0, 要插入的项, ... ...);
(3) 替换:可以向指定位置插入任意数量的项,同时删除任意数量的项,最少需要三个参数:splice(要删除的第一项位置即插入起始位置, 要删除的项数, 要插入的项, ... ...);
var colors = [ "red", "green", "blue" ]; var removed = colors.splice(0, 1); // 删除第一项 console.log(colors); // "green", "blue" console.log(removed); // "red" removed = colors.splice(1, 0, "yellow", "orange"); // 从位置1插入两项 console.log(colors); // "green","yellow","orange","blue" console.log(removed); // 返回一个空数组 removed = colors.splice(1, 2, "red", "purple"); // 删除两项,插入一项 console.log(colors); // "green","red","purple","orange","blue" console.log(removed); // "yellow"
位置方法
indexOf()和lastIndexOf()
这两个方法都接收两个参数:“要查找的项”和“查找起点位置的索引(可选)”
var nubmers = [ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]; console.log(numbers.indexOf(4)); // 3 console.log(numbers.lastIndexOf(4)); // 5 console.log(numbers.indexOf(4, 4)); // 5 console.log(numbers.lastIndexOf(4, 4)); // 3 var person = { name: "zaofan" }; var people = [ { name: "zaofan" } ]; var morePeople = [ person ]; console.log(people.indexOf(person)); // -1 console.log(morePeople.indexOf(person)); // 0
迭代方法
ECMAScript 5 为数组提供了5个迭代方法,每个方法都接收两个参数:“在每一项上运行的函数”和“运行该函数的作用于对象--影响this的值(可选)”
1.every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true;
2.fiter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组;
3.forEach():对数组中的每一项运行给定函数,无返回值;
4.map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组;
5.some(): 对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true;
var numbers = [ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]; var everyResult = numbers.every(function (item, index, array) { return (item > 2); }); console.log(everyResult); // false var someResult = numbers.som(function (item, index, array) { return (item > 2); }); console.log(someResult); // true var filterResult = numbers.filter(function (item, index, array) { return (item > 2); }); console.log(filterResult); // [ 3, 4, 5, 4, 3 ] var mapResult = numbers.map(function (item, index, array) { return item * 2; }); console.log(mapResult); // [ 2, 4, 6, 8, 10, 8, 6, 4, 2 ] numbers.forEach(function (item, index, array) { // 针对数组每一项执行操作 });
缩小方法
reduce()和reduceRight()
这两个方法都会迭代数组的所有项,然后构建一个最终的返回值。
reduce()从第一项开始遍历到最后一项,reduceRight()从最后一项开始向前遍历到第一项。
传给reduce()和reduceRight()的函数接收4个参数:前一个值,当前值,项的索引,数组;reduce()第一次迭代时,第一个参数是第一个项,第二个参数是第二个项,reduceRight()与之相反。
var values = [ 1, 2, 3, 4, 5 ]; var sum = values.reduce(function (prev, cur, index, array) { console.log(prev, cur); return prev + cur; }); console.log(sum); // 1,2 // 3,3 // 6,4 // 10,5 // 15 sum = values.reduceRight(function (prev, cur, index, array) { console.log(prev, cur); return prev + cur; }); console.log(sum); // 5, 4 // 9, 3 // 12, 2 // 14, 1 // 15
总结
以上内容你们可能会发现很多来自相关书籍,请见谅。