学习在于总结,自己总觉得书到用时方恨少。
数组是javascript编程中的重中之重,归纳整理的这些数组方法,也是希望自己能够更全面一些的了解数组知识点,某天忘记了,也可以再回头看看,也希望能和大家一起分享,一起成长。
数组的基本概念
什么是数组
- 数组是一组数据结合而成的有序列表
- 数组是一个对象,用于在单个变量中存储多个值
数组的特点
- ECMAScript数组的每一项都可以保存任意类型的数据(比如:数组的第一个位置来保存字符串,第二个位置来保存数值,第三个位置保存对象)
- ECMAScript数组的大小是可以动态调整的,例如:可以随着数据的添加自动增长,来容纳新增数据
- ECMAScript数组是一块连续的内存空间,以下标来描述空间的位置
创建数组的方式
-
Array构造函数的方式
var arr = new Array(); //创建一个空数组 [] var arr = new Array(3); //创建一个length为3的数组 [undefined, undefined, undefined] var arr = new Array("red","yellow","green"); //创建数组并赋值 ["red", "yellow", "green"] 复制代码
-
数组字面量表示法
var arr = []; //创建一个空数组 var arr = ["red","yellow","green"]; //创建了一个包含3个字符串的数组 var arr = [1,2,]; //不要这样,会创建一个包含2或3项的数组,出现兼容问题 var arr = [,,,]; //不要这样,会创建一个包含3或4项的数组,出现兼容问题 复制代码
-
of方法(ES6方法)
var arr = Array.of(7); // 创建数组并赋值 [7] var arr = Array.of(1, 2, 3); // 创建数组并赋值 [1, 2, 3] 复制代码
数组的属性(length、prototype、 constructor)
-
length
length设置或返回数组中元素的数目。
length很有特点,它不是只读的,可以通过length这个属性,从数组的末尾移除项或向数组中添加新项
var arr = ["red","yellow","green"]; arr.length = 2; //把arr修改为length为2的数组,即当length属性被设置得比原来小时,则原先数组中索引大于或等于length的元素的值全部被丢失。 console.log(arr[2]); //undefined var colors = ["black","white","blue"]; colors.length = 4; // 如果将其length设置为大于数组项数的值,则新增的每一项都会取undefined值,但实际数组的状态不会发生变化,仍旧是["black","white","blue"] console.log(colors[3]); //undefined 复制代码
-
prototype
prototype 属性是 object 共有的。
一般用来给数组实例添加属性和方法。
-
constructor
表示创建对象的函数。返回对创建此对象的数组函数的引用。
说明:constructor 属性是所有具有 prototype 的对象的成员。constructor 属性保存了对构造特定对象实例的函数的引用。
数组的检测
-
instanceof
instanceof 用来检测一个实例是否属于某个类,弥补了typeof不能检测具体属于哪个对象的局限性(也就是说如果一个实例是object类型的,typeof无法分清这个对象是属于对象中的数组还是对象中的正则,只能判断该类型为是一个object)。
尽管不像 typeof 方法那样灵活,但是在 typeof 方法返回 "object" 的情况下,instanceof 方法还是很有用的。
原理:只要在当前实例原型链上的对象,我们用其检测出来的都是true
注意:但是在类的原型继承中,我们最后检测出来的结果未必正确
var num =10; var arr = [1,2,3]; console.log(num instanceof Number); //false 因为instanceof不能用于检测和处理字面量方式创建出来的基本数据类型值 console.log(arr instanceof Object); //true console.log(arr instanceof Array); //true 复制代码
-
constructor
constructor 构造函数 是函数原型上的属性,该属性指向的是构造函数本身
作用和instsnceof非常相似,与instanceof不同的是,不仅可以处理引用数据类型,还可以处理原始数据类型。
var num = 10; var arr = [1,2,3]; console.log(num.constructor == Number); //true console.log(arr.constructor == Object); //false console.log(arr.constructor == Array); //true 由于constructor可以被重写,所以不能确保一定是数组 // 局限性:我们可以把类的原型进行重写,在重写的过程中很可能把之前constructor给覆盖了,这样检测出来的结果就是不准确的。例如: function Fn() {}; var f = Fn; console.log(f.constructor); //ƒ Fn() {} console.log(f.constructor == Function); //true Fn.prototype = new Array; var f = new Fn; //f是一个函数,按道理说他的构造函数应该是Function,但是修改其原型链后,它的constructor变成了Array. console.log(f.constructor); //ƒ Array() { [native code] } console.log(f.constructor == Array); //true 复制代码
-
Array.isArray(obj)
isArray() 方法用于判断一个对象是否为数组。效率较高。
var arr = [1,2,3]; var isArr = Array.isArray(arr); console.log(isArr); //true 复制代码
-
Object.prototype.toString.call()
原型链上的Object对象的toString方法
Object.prototype.toString的作用是返回当前方法的执行主体(方法中的this)所属类的详细信息,是最全面也是最常用的检测数据类型的方式。
var arr = [34,65,1]; Object.prototype.toString.call(arr) === '[object Array]' //return true 复制代码
// Object.prototype.toString.call() 用法 console.log(Object.prototype.toString.call(1)); //[object Number] console.log(Object.prototype.toString.call(/^sf/)); //[object RegExp] console.log(Object.prototype.toString.call("hello")); //[object String] console.log(Object.prototype.toString.call(true)); //[object Boolean] console.log(Object.prototype.toString.call(null)); //[object Null] console.log(Object.prototype.toString.call(undefined)); //[object Undefined] console.log(Object.prototype.toString.call(function() {})); //[object Function] console.log(typeof(Object.prototype.toString.call(function() {}))); //string 复制代码
数组方法
转换方法( join)
-
arr.join(separator)
把数组构构造成字符串,它先把数组中的每个元素转换成字符串,然后再用 separator 分隔符把它们链接在一起,separator 分隔符默认是逗号 “,”,要想做到无间隔链接,可以使用空字符串作为 separator:
var arr = [1,2,3,4,5] arr.join('|'); //"1|2|3|4|5" arr.join(""); //12345 //另所有对象有具有的 toLocaleString、toString、valueOf,可以看作是join的特殊用法,不常用 复制代码
栈方法(push、pop)
-
arr.push(item…)
将一个或多个新元素添加到数组结尾,并返回数组新长度。
var arr=[1,2,3,4,5]; arr.push(6); // 往数组arr中推入另外一项 6 console.log(arr); // [1, 2, 3, 4, 5, 6] 复制代码
-
arr.pop()
移除最后一个元素并返回该元素值。
var arr=[1,2,3,4,5]; var arrItem = arr.pop(); // 移除最后一个元素,并返回该元素的值 console.log(arrItem); //5 console.log(arr); //[1,2,3,4] 复制代码
队列方法(unshift、shift)
-
arr.unshift(item)
在数组的前端添加任意个项,并返回新的数组的长度。
var arr=[1,2,3,4,5]; arr.unshift(0); // 往数组arr中推入另外一项 0 console.log(arr); // [0,1, 2, 3, 4, 5] 复制代码
-
arr.shift()
从数组中获得第一项,并返回该元素值。
var arr=[1,2,3,4,5]; var arrItem = arr.shift(); // 移除第一一个元素,并返回该元素的值 console.log(arrItem); //1 console.log(arr); //[2,3,4,5] 复制代码
重排序方法(reverse、sort)
-
arr.reverse()
反转数组顺序。
var arr = [2,3,1,5,4]; arr.reverse(); console.log(arr); // [4, 5, 1, 3, 2] 复制代码
-
arr.sort()
重新排列数组顺序,默认升序。
// var arr = [20,3,12,1,5,4]; arr.sort(Fn); console.log(arr); // [1, 12, 20, 3, 4, 5],可见单纯的使用sort并没有达到理想的升序结果 var arr = [20,3,12,1,5,4]; arr.sort((a, b) => (a - b)); // (6) [1, 3, 4, 5, 12, 20] 复制代码
操作方法(concat、slice、splice、 copyWithin、 fill)
-
arr.concat(item) 不影响原始数组
concat()方法会基于当前数组中的所有项创建一个新数组,也就是concat()方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。
var colors = ["red","green","blue"]; var colors2 = colors.concat("yellow",["black","brown"]); console.log(colors); //["red", "green", "blue"] console.log(colors2); //["red", "green", "blue", "yellow", "black", "brown"] 复制代码
-
arr.slice(start, end) 不影响原始数组
slice()方法基于当前数组中的一个或多个项创建一个新数组。
slice()方法可以接受一个或两个参数,即要返回项的起始(包括起始位置项)和结束位置(不包括结束位置项)。
字符串也有个同名方法 string.slice。
var colors = ["red", "green", "blue", "yellow", "black", "brown"]; var colors1 = colors.slice(1); //截取从colors[1]到最后一项的,返回新数组 var colors2 = colors.slice(1,4); //截取从colors[1]到colors[3],返回新数组 var colors3 = colors.slice(-5,-2); // 此种情况,如果结束位置小于起始位置,则返回空数组 console.log(colors); // ["red", "green", "blue", "yellow", "black", "brown"] console.log(colors1); // ["green", "blue", "yellow", "black", "brown"] console.log(colors2); // ["green", "blue", "yellow"] console.log(colors3); // ["green", "blue", "yellow"] 复制代码
-
arr.splice(start, deleteCount, item…) 影响原始数组
splice()方法从 arr 中移除一个或多个元素,并将新的 item 插入至移除元素的开始位置, 参数 start 是移除元素的开始位置,deleteCount 是要移除的元素的个数,item 是要被插入的元素。它返回一个包含被移除元素的数组。
// 删除 var colors1 = ["red", "green", "blue", "yellow", "black", "brown"]; var removed = colors1.splice(0,1); //从第0个开始,移除1项,并返回移除的内容 console.log(colors1); //(5) ["green", "blue", "yellow", "black", "brown"] console.log(removed); //["red"] // 插入 var colors2 = ["red", "green", "blue", "yellow", "black", "brown"]; var removed = colors2.splice(1,0,"orange","purple"); //从第1项开始,移除0项,插入"orange","purple",并返回移除的内容 console.log(colors2); //(8) ["red", "orange", "purple", "green", "blue", "yellow", "black", "brown"] console.log(removed); //[] // 替换 var colors3 = ["red", "green", "blue", "yellow", "black", "brown"]; var removed = colors3.splice(1,1,"orange","purple"); //从第1项开始,移除1项,插入"orange","purple",并返回移除的内容 console.log(colors3); //(7) ["red", "orange", "purple", "blue", "yellow", "black", "brown"] console.log(removed); //["green"] 复制代码
-
arr.copyWithin(target, start, end) 影响原始数组
arr.copyWithin()该方法复制数组的一部分到同一数组中的另一个位置(会覆盖原成员),并返回修改后的数组。使用这个方法,会修改当前数组。
参数 target 为开始替换数据的位置,若 target 大于等于 arr.length,将会不发生拷贝。
start 是可选参数,为开始读取数据的位置,默认为0。
end 是可选参数,为停止读取数据的位置,默认为 arr.length。
var arr = [1, 2, 3, 4, 5]; arr.copyWithin(0, 3); // 将从3号位直到数组结束的成员(4和5),复制到从0号位开始的位置,结果覆盖了原来的1和2。 console.log(arr); // [4, 5, 3, 4, 5] 复制代码
-
arr.fill(value,start,end) 影响原始数组
该方法使用给定值填充一个数组,参数 value 是用来填充数组的值。start 是可选参数,为填充开始位置,默认为 0。end 是可选参数,为填充的结束位置,默认为 arr.length。
[1, 2, 3].fill(4) // [4, 4, 4] [1, 2, 3].fill(4, 1 , 2) // [1, 4, 3] 复制代码
位置方法(indexOf、 lastIndexOf、includes)
-
arr.indexOf(searchElement, start)
该方法返回要查找的项在数组中的位置,如果没找到返回 -1。
接受两个参数,searchElement 是要查找的项,start 是查找起始位置的索引,默认是0。
var numbers = [1,2,3,4,5,4,3,2,1]; console.log(numbers.indexOf(2)); //1 查找2,从第0项开始,往后找 console.log(numbers.indexOf(2,3)); //7 查找2,从第3项开始,包括第三项,往后找 console.log(numbers.indexOf(8,3)); //-1 查找8,从第3项开始 复制代码
-
arr.lastIndexOf(searchElement, start)
从 start 位置开始向前查找,start 默认值为 arr.length – 1。
注意该方法在比较查找项与数组中每一项时,会使用全等操作符,也就是要求查找的项必须严格相等。
var numbers = [1,2,3,4,5,4,3,2,1]; console.log(numbers.lastIndexOf(2)); //7 查找2,从最后一项开始,往前找 console.log(numbers.lastIndexOf(2,3)); //1 查找2,从第3项开始,包括第三项,往前找 复制代码
-
arr.includes(searchElement, fromIndex)
var numbers = [1,2,3,4,5,4,3,2,1]; console.log(numbers.includes(2)); //true 查找2,从第0项开始,如果有,则返回true,否则返回false console.log(numbers.includes(4,6)); //false 查找4,从第76项开始,如果有,则返回true,否则返回false 复制代码
迭代方法(every、 some、 filter、 forEach、 map、 find、 findIndex、entries、keys、values)
每个迭代方法都接收两个参数:1、要在每一项上运行的函数( callback);2、运行该函数的作用域对象(thisArg)——影响this值。
传入这些方法中的函数会接收三个参数:1、数组项的值;2、该项在数组中的位置;3、数组对象本身
-
arr.every(callback,thisArg)
对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
var numbers = [1,2,3,4,5,4,3,2,1]; var everyItem = numbers.every((item,index,array) => (item>2)); console.log(everyItem); //false 复制代码
-
arr.some(callback, thisArg)
some()和every()很像,some()对数组中的每一项运行给定函数,如果该函数对某一项返回 true,则返回 true。
var numbers = [1,2,3,4,5,4,3,2,1]; var everyItem = numbers.some((item,index,array) => (item>2)); console.log(everyItem); //true 复制代码
-
arr.filter(callback, thisArg)
对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组。
var numbers = [1,2,3,4,5,4,3,2,1]; var everyItem = numbers.filter((item,index,array) => (item>2)); console.log(numbers); //(9) [1, 2, 3, 4, 5, 4, 3, 2, 1] console.log(everyItem); //(5) [3, 4, 5, 4, 3] 复制代码
-
arr.forEach(callback)
对数组中的每一项运行给定函数,这个方法没有返回值。本质上与使用 for 循环迭代数组一样。
var numbers = [1,2,3,4,5,4,3,2,1]; var everyItem = numbers.forEach((item,index,array) => { // 运行某些操作 }); 复制代码
-
arr.map(callback)
对数组中的每一项运行给定函数,返回每次函数调用组成的数组。
var numbers = [1,2,3,4,5,4,3,2,1]; var everyItem = numbers.map((item,index,array) => item*2); console.log(numbers); //(9) [1, 2, 3, 4, 5, 4, 3, 2, 1] console.log(everyItem); //(9) [2, 4, 6, 8, 10, 8, 6, 4, 2] 复制代码
-
arr.find(callback, thisArg)
该方法对数组所有成员依次执行 callback 函数,直到找出第一个返回值为 true 的成员,然后返回该成员。如果没有符合条件的成员,则返回 undefined。
[1, 4, -5, 10].find((v, i, arr) => v < 0); // -5 复制代码
-
arr.findIndex(callback, thisArg)
该方法与 arr.find() 类似,对数组中的成员依次执行 callback 函数,直至找到第一个返回值为 true 的成员,然后返回该成员的索引。如果没有符合条件的成员,则返回 -1。
[1, 5, 10, 15].findIndex((v, i , arr)=>{ return v > 9 }) //2 复制代码
-
arr.entries()、 arr.keys()、 arr.values()
这三个方法都返回一个新的Array Iterator对象,可以用
for...of
循环进行遍历,区别是keys()
是对键名的遍历、values()
是对键值的遍历,entries()
是对键值对的遍历。for (let index of ['a', 'b'].keys()) { console.log(index); } // 0 // 1 for (let elem of ['a', 'b'].values()) { console.log(elem) ;} // 'a' // 'b' for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem);} // 0 "a" // 1 "b" var arr = ["a", "b"; var iterator = arr.entries(); // undefined console.log(iterator); // Array Iterator {} console.log(iterator.next().value); // [0, "a"] console.log(iterator.next().value); // [1, "b"] 复制代码
归并方法(reduce、 reduceRight)
数组的reduce()和reduceRight()这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。
他们都接收4个参数:1、前一个值;2、当前值;3、项的索引;4、数组对象
-
arr.reduce(callback, intialValue)
reduce()方法从数组的第一项开始,逐个遍历到最后。
var values = [1,2,3,4,5]; var sum = values.reduce((prev,cur,index,array) => { console.log(prev,cur) // 1 2 // 3 3 // 6 4 // 10 5 return prev + cur }) console.log(sum); //15 复制代码
-
arr.reduceRight(callback,intiaValue)
reduceRight()方法从数组的最后一项开始,逐个遍历到第一项。
var values = [1,2,3,4,5]; var sum = values.reduceRight((prev,cur,index,array) => { console.log(prev,cur); //5 4 // 9 3 // 12 2 // 14 1 return prev + cur }) console.log(sum); //15 复制代码
参考文章
如若发现文中纰漏请留言,欢迎大家纠错,我们一起成长。