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); // 10002
  • arr.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); // 3
  • arr.every(function(item, [index], [arr]){},[thisValue]):检测数值元素的每个元素是否都符合条件,有一个不满足则返回false,相当于&&
 let arr = [1,99,9999,10002];
 let hasMoney = arr.every(item=>{
   return item > 10000;
 });
 console.log(hasMoney); // false
  • arr.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]):从数组的startend为止复制元素到数组的target位置中。

数组拷贝

数组拷贝完全可以单独拎出来说,涉及赋值、深拷贝和浅拷贝,偶尔会遇到诸如“我复制了a数组,修改b数组后,a数组咋也变了”的迷茫,我们应该在避免的同时了解其原理所在,用一个表格来归纳总结他们的区别:

定义名称和原数据是否指向同一对象第一层数据为基本数据类型原数据中包含子对象
赋值改变会使原数据一同改变改变会使原数据一同改变
浅拷贝改变不会使原数据一同改变改变会使原数据一同改变
深拷贝改变不会使原数据一同改变改变不会使原数据一同改变

可以看出,赋值的数组指向的堆内存是一样的,所以不管是修改基本数据类型还是数组对象里的元素,都会导致原数组改变;

深拷贝得到一个全新的数组,与被拷贝的数组断绝了联系性,改什么都不会影响到原数组,即:拷贝所有的属性值,以及属性地址指向的值的内存空间;
而浅拷贝就是个半吊子,如果是数组里全是基本数据类型的元素,他修改后不会影响到原数组,而一旦存在复杂一点的数组对象,他就没辙了,还得去修改原数据,借用前人对浅拷贝通俗易懂的定义:只拷贝第一层的原始类型值,和第一层的引用类型地址。

浅拷贝

  1. 对象的合并 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};
  1. 对象的解构赋值
  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};
  1. 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()属于浅拷贝。

深拷贝

  1. 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"];
  1. 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);
  1. 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])}:主要用于获取对象的键名。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值