写给前端🥬🐕的常用js处理数据的方法

888 阅读5分钟

假如有一个前端🥬🐕,总是需要你去教他怎样去做数据处理,以下是一些常用的处理方法总结的基本用法,可以完成大部分数据的处理,下次问你的时候就拿出来让她看吧

数组的方法

Array对象的原型中有不少处理数组的方法,以下列举一些常用的方法

includes

适用情况:检查数组中是否有此项

let foods = ["汤粉", "螺蛳粉", "煲仔饭", "酸菜鱼"];
let res = foods.includes('奶茶');
console.log(res) //false

let res2 = foods.includes('煲仔饭');
console.log(res2) //true

join

适用情况:将数组每一项中间插入分隔符拼接成字符串

原数组不会改变

let foods = ["汤粉", "螺蛳粉", "煲仔饭", "酸菜鱼"];
let msg = foods.join('?');
console.log(msg) //汤粉?螺蛳粉?煲仔饭?酸菜鱼

concat

适用情况:拼接数组 传入数组就会拼接数组,传入非数组就会作为一项添加进数组里面

原数组不会改变

let arr = ["汤粉", "螺蛳粉"];
let arr2 = [ "煲仔饭", "酸菜鱼"];
let res = arr.concat(arr2 , "虾饺");
console.log(res)//['汤粉', '螺蛳粉', '煲仔饭', '酸菜鱼', '虾饺']

flat

适用情况:数组扁平化

let arr = [["汤粉", "螺蛳粉",["煲仔饭"]],["虾饺"]];
arr.flat(Infinity) //['汤粉', '螺蛳粉', '煲仔饭', '虾饺']

forEach

适用情况:遍历数据均可用

优点:几乎适用于任何情况,相比其他方法所用时间最少

缺点:某些情况下,和其他方法相比,没有其他方法便捷和优雅

let arr = [
	{ value: '第一项' },
	{ value: '第二项' }
];
arr.forEach((item,index)=>{
	item.value += index
	// return item + index 返回的数据不会被接受
})
console.log(arr)
//[
//	{ value: '第一项0' },
//	{ value: '第二项1' }
//]

需要注意的是forEach方法的第一个参数是一个函数,在这个函数里面 return 数据,是不会被接收的,return只会打破当前循坏,进行下一个循环,相当于continue

一般用于: 改变原数组的数据 或 对原数据某个项做处理

map

适用情况:将对原数组进行处理后,返回数据处理后的新数组

优点:可以不改变原数组,代码优雅

缺点:适用情况比 forEach 少

let arr = [
	{ value: '第一项' },
	{ value: '第二项' }
];
let newArr = arr.map((item,index) => {
	return { ...item, index }
})
console.log(newArr)
//[
//	{ value: '第一项', index: 0 },
//	{ value: '第二项', index: 1 }
//]

filter

适用情况:对数组过滤,返回一个符合条件的项组成的数组

let arr = [
	{ value: '第一项', disabled: true },
	{ value: '第二项' },
	{ value: '第三项', disabled: true },
];
let newArr = arr.filter(item => item.disabled)
console.log(newArr)
//[
//	{ value: '第一项', disabled: true },
//	{ value: '第三项', disabled: true },
//]

find

适用情况:返回数组中符合条件的第一项

let arr = [
	{ value: '第一项' },
	{ value: '第二项', disabled: true },
	{ value: '第三项', disabled: true },
];
let item = arr.find(item => item.disabled)
console.log(item)
// { value: '第二项', disabled: true }

findIndex

适用情况:同上,返回的是index

let arr = [
	{ value: '第一项' },
	{ value: '第二项', disabled: true },
	{ value: '第三项', disabled: true },
];
let index = arr.findIndex(item => item.disabled)
console.log(index) // 1

需要注意的是,如果没有符合条件的项,返回的是-1

some

适用情况:寻找数组是否有符合条件的项,如果有,返回true

let arr = [
	{ value: '第一项' },
	{ value: '第二项', disabled: true },
	{ value: '第三项', disabled: true },
];
let res = arr.some(item => item.disabled)
console.log(res) // true

every

适用情况:寻找数组是否每一项都符合条件,如果是,返回true

let arr = [
	{ value: '第一项', disabled: true },
	{ value: '第二项', disabled: true },
	{ value: '第三项', disabled: true },
];
let res = arr.every(item => item.disabled)
console.log(res) // true

其他

数组还有很多其他方法,但是不常用 用以上的这些方法可以完成90%的数据处理 如果想不到用什么方法的话,用 基本的for循环 也可以完成100%的处理

其他方法用法:

fill() 数组填充

at(index) 返回该index的item

copyWithin 复制数组自身部分到自身特定位置

对象的方法

Object.keys

适用情况:将对象的全部key以数组的形式返回,在处理数据中经常会用到

let obj = {
	'name': 'xiaobai',
	'age': 18,
	'sex': 'female'
}
let arr = Object.keys(obj);
console.log(arr) //['name', 'age', 'sex']

Object.assign

适用情况合并对象,需注意是浅拷贝

let obj = {
	'name': 'xiaobai',
	'age': 18,
	'sex': 'female'
}
let obj2 = Object.assign({ occupation: 'student' });
console.log(obj2) 
// { name: 'xiaobai', age: 18, sex: 'female', occupation: 'student' }

三点运算符

适用情况:数组或对象解构,可用于合并对象

let obj = {
	'name': 'xiaobai',
	'age': 18,
	'sex': 'female'
}
let obj2 = { ...obj,age: 20 }
console.log(obj2) 
// { name: 'xiaobai', age: 20, sex: 'female' }
let arr = ["汤粉", "螺蛳粉", "煲仔饭", "酸菜鱼"];
let arr2 = [...arr, "虾饺"]
console.log(arr2) 
// ['汤粉', '螺蛳粉', '煲仔饭', '酸菜鱼', '虾饺']

深拷贝的方法

JSON.stringify() 和 JSON.parse()

一般情况下使用JSON的方法可以对数据深拷贝,但是无法复制function、RegExp正则对象、Date时间对象

如果不含有function、RegExp正则对象、Date时间对象的数据结构,使用JSON深拷贝即可

let arr = [{
	reg: /\d/,
	date: new Date(),
	fn: a => a+1,
},{
	str: 'str',
	num: 996,
}];
let arr2 = JSON.parse(JSON.stringify(arr));
console.log(arr2);
// [{
//	 reg: {}
//	 date: "2022-05-20T08:20:36.413Z"
// },{
//	 str: 'str',
//	 num: 996,
// }]

可看到function被拷贝成undefined,Date时间对象被拷贝成一个字符串,正则对象被拷贝成空对象

说明JSON拷贝方式不适用于有以上含对象的对象,但一般业务代码不会含有以上的对象,直接使用JSON处理即可

递归

以下方法可适用绝大部分深拷贝场景

需注意的是 该方法对函数的复制是浅拷贝,如果有需求可添加Function类型

function clone(obj) {
  // 当null NaN undefined number string等基本数据类型时直接返回
  if (obj === null || typeof obj !== 'object') {
    return obj
  }
  // Date类型
  if (obj instanceof Date) {
    const copy = new Date()
    copy.setTime(obj.getTime())
    return copy
  }
  // function类型
  if (obj instanceof Function) {
    return obj
  }
  // 正则类型类型
  if (obj instanceof RegExp) {
    const Constructor = obj.constructor
    return new Constructor(obj)
  }
  // 如果是数组等引用数据类型
  if (obj instanceof Array || obj instanceof Object) {
    const copyObj = Array.isArray(obj) ? [] : {}
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        copyObj[key] = clone(obj[key])
      }
    }
    return copyObj
  }
}

该方法是一种深拷贝,但是对Function对象是浅拷贝,是直接返回指针出去的,因为一般情况是不需要对函数进行深拷贝的,一般指向同一个函数即可