JS常用数组操作
前言
在循环数组时或多或少会对数组进行处理,而JS提供了很多Array对象方法供我们使用,熟练使用和记录备忘是必须的。话不多说,以下是归纳整理相应的方法:
数组增添
arr.push(item,item1,...)
:向数组的末尾添加一个或更多元素,并返回新的长度。arr.unshift(item,item1,...)
:向数组的开头添加一个或更多元素,并返回新的长度。arr.splice(index,num,item1,...,itemN)
:从数组中添加或删除元素。注:当item
的总数量大于num
时为添加元素,返回添加元素之后的数组。
数组删除
arr.pop()
:删除数组的最后一个元素并返回删除的元素。arr.shift()
:移除数组第一个元素并返回该元素值,数组中元素自动前移。arr.splice(index,num)
:从数组中添加或删除元素。注:删除从index
开始的共num
个的元素,返回所移除元素的数组。
数组查找
arr.includes(item,[index])
:从index
下标开始判断数组是否包含item
,返回布尔值。arr.indexOf(item,[index])
:从index
下标开始搜索数组中的元素,并返回item
第一次出现的位置(下标)。arr.lastIndexOf(item,[index])
:从index
下标开始搜索数组中的元素,并返回item
最后出现的位置(下标)。arr.include(item,[index])
:从index
下标开始搜索数组是否包含value,包含返回0,不包含返回-1。arr.find(function(item, [index], [arr]){},[thisValue])
:从index
开始查找arr
中符合传入回调函数条件的第一个item
。返回符合回调函数条件的数组第一个元素值(对象/基础数据类型),如果没有符合条件的则返回undefined
。let arr = [1,99,9999,10002];
let myMoney = arr.find((item,index,arr)=>{
return item > 10000;
});
console.log(myMoney); // 10002arr.findIndex(function(item, [index], [arr]){},[thisValue])
:从index
开始查找arr
中符合传入回调函数条件的第一个item
元素索引。返回符合测试条件的第一个数组元素索引,如果没有符合条件的则返回-1。let arr = [1,99,9999,10002];
let moneyIndex = arr.findIndex((item,index,arr)=>{
return item > 10000;
});
console.log(moneyIndex); // 3arr.every(function(item, [index], [arr]){},[thisValue])
:检测数值元素的每个元素是否都符合条件,有一个不满足则返回false
,相当于&&
。let arr = [1,99,9999,10002];
let hasMoney = arr.every(item=>{
return item > 10000;
});
console.log(hasMoney); // falsearr.some(function(item, [index], [arr]){},[thisValue])
:检测数组元素中是否有元素符合指定条件,有一个满足则返回true
,相当于||
。let arr = [1,99,9999,10002];
let hasMoney = arr.some(item=>{
return item > 10000;
});
console.log(hasMoney); // true
数组截取
arr.slice(start,[end])
:截取从start
下标开始的元素到end
,以数组的形式返回截取后的数组。注:不包括end
对应的元素,若省略end
则会得到start
之后的所有元素。
数组合并
arr.concat(arr1,arr2,...)
:连接两个或更多的数组(也可以是字符串),返回连接好的新的数组。
数组排序
arr.sort([function(){}])
:对数组的元素进行排序,默认为按字母升序,可通过function()
函数自定义排序规则,返回排序后的数组。arr.reverse()
:彻底反转数组的元素顺序,返回颠倒顺序后的数组。- 数字数组升序:
arr.sort(function(a,b){ return a-b })
- 数字数组降序:
arr.sort(function(a,b){ return b-a })
- 字母数组降序:
arr.sort();arr.reverse();
注意是先排序再反转即可。
数组变形
arr.join([separator])
:把数组中的所有元素转换为一个字符串,separator
可指定分隔符,如果省略该参数,则使用逗号作为分隔符。arr.toString()
:把数组转换为字符串,返回值与没有参数的join()
方法返回的字符串相同。- 此处插入与之相对的字符串变形成数组法:
str.split(separator,maxLength)
,separator
为字符串的分隔符,maxLength
为返回数组的最大长度。
数组复制
arr.copyWithin(target,[start],[end])
:从数组的start
到end
为止复制元素到数组的target
位置中。
数组拷贝
数组拷贝完全可以单独拎出来说,涉及赋值、深拷贝和浅拷贝,偶尔会遇到诸如“我复制了a数组,修改b数组后,a数组咋也变了”的迷茫,我们应该在避免的同时了解其原理所在,用一个表格来归纳总结他们的区别:
定义名称 | 和原数据是否指向同一对象 | 第一层数据为基本数据类型 | 原数据中包含子对象 |
---|---|---|---|
赋值 | 是 | 改变会使原数据一同改变 | 改变会使原数据一同改变 |
浅拷贝 | 否 | 改变不会使原数据一同改变 | 改变会使原数据一同改变 |
深拷贝 | 否 | 改变不会使原数据一同改变 | 改变不会使原数据一同改变 |
可以看出,赋值的数组指向的堆内存是一样的,所以不管是修改基本数据类型还是数组对象里的元素,都会导致原数组改变;
深拷贝得到一个全新的数组,与被拷贝的数组断绝了联系性,改什么都不会影响到原数组,即:拷贝所有的属性值,以及属性地址指向的值的内存空间;
而浅拷贝就是个半吊子,如果是数组里全是基本数据类型的元素,他修改后不会影响到原数组,而一旦存在复杂一点的数组对象,他就没辙了,还得去修改原数据,借用前人对浅拷贝通俗易懂的定义:只拷贝第一层的原始类型值,和第一层的引用类型地址。
浅拷贝
对象的合并 Object.assign(),第一个参数必须是个空对象。
let obj1 = { a: { x:6, y:9}, b: 2};
let obj2 = Object.assign({ }, obj1);
obj2.a.y = 99;
obj2.b = 88;
// 结果
console.log(obj1); // {a: {x:6, y:99}, b: 2};
console.log(obj2); // {a: {x:6, y:99}, b: 88};对象的解构赋值
let obj1 = { a: { x:6, y:9}, b: 2};
let obj2 = { …obj1};
obj2.a.y = 99;
obj2.b = 88;
// 结果
console.log(obj1); // {a: {x:6, y:99}, b: 2};
console.log(obj2); // {a: {x:6, y:99}, b: 88};arr.slice()
/arr.concat()
方法。let arr1 = [{ x:’six’,y:’nine’},”two”];
let arr2 = arr1.slice(0);
arr2[1] = “cool”;
arr2[0].y = ‘ice’;
// 结果
console.log(arr1); // [{x:’six’,y:’ice’},”two”]
console.log(arr2); // [{x:’six’,y:’ice’},”cool”];let arr1 = [{ x:’six’,y:’nine’},”two”];
let arr2 = arr1.concat();
arr2[1] = “cool”;
arr2[0].y = ‘ice’;
// 结果
console.log(arr1); // [{x:’six’,y:’ice’},”two”]
console.log(arr2); // [{x:’six’,y:’ice’},”cool”];
结论:对象的Object.assign()
、解构赋值,数组的arr.slice(0)
和arr.concat()
属于浅拷贝。
深拷贝
JSON对象的
JSON.stringify()
与JSON.parse()
,但数据过多会有递归爆栈的风险。function deepClone(obj){
let myObj = JSON.stringify(obj);
let objClone = JSON.parse(myObj);
return objClone
}
let arr1 = [{ x:’six’,y:’nine’},”two”];
let arr2 = deepClone(arr1);
arr2[1] = “cool”;
arr2[0].y = ‘ice’;
// 结果
console.log(arr1); // [{x:’six’,y:’nine’},”two”]
console.log(arr2); // [{x:’six’,y:’ice’},”cool”];JQ工具库:
$.extend([deep], target, obj1,...,[objN])
,deep表示是否深拷贝,为true
为深拷贝,为false
为浅拷贝。target
目标对象,其他对象的成员属性将被附加到该对象上,obj1到objN是第一个以及第N个被合并的对象。//第一个参数不传(false是不能够显示的写出来的)默认为false,是浅拷贝。传true为深拷贝。
$.extend(true,object1, object2)
//newObject,newArrary即为深拷贝出来的对象和数组
var newObject = $.extend(true, { }, object);
var newArrary = $.extend(true, [], newArrary);lodash.cloneDeep(object)
实现深拷贝。lodash是一个一致性、模块化、高性能的JavaScript实用工具库。
数组循环
迭代:
arr.forEach(function(item, [index], [arr]){},[thisValue])
,调用数组的每个元素,并将元素传递给回调函数。let arr = [1,99,9999,10002];
let money = [];
arr.forEach((item,index,arr)=>{
if(item <= 99){return;
}
money.push(item); // [9999,10002]
});汇总:
arr.reduce(function(total, item, [index], [arr]){},[thisValue])
,将数组元素计算为一个值(从左到右),arr.reduceRight()
与之相反。let arr = [1,99,9999,10002];
let myMoney = arr.reduce((total,item)=>{
return total + item;
});
console.log(myMoney); // 20101过滤器:
arr.filter(function(item, [index], [arr]){},[thisValue])
,检测数值元素,并返回符合条件所有元素的数组。let arr = [1,99,9999,10002];
let myMoney = arr.filter((item,index,arr)=>{
return item <= 99;
});
console.log(myMoney); // [1,99]映射:
arr.map(function(item, [index], [arr]){},[thisValue])
:通过指定函数处理数组的每个元素,并返回处理后的数组。let arr = [1,99,9999,10002];
let money = [];
arr.forEach((item)=>{
if(item>1 && item< 9999){console.log(item)
money.push(item); // [99]
}
});for(ler prop in obj){console.log(prop,obj[prop])}
:主要用于获取对象的键名。
还没有评论,来说两句吧...