【JavaScript】对象的复制和引用处理方法

JavaScript 把{}[]都当作对象Object类型,在调用函数传递的参数中,对象Object只能被引用,不会深度拷贝,下面讲一些关于JavaScript对象的常用处理方法

1.数组对象

JavaScript 有对数组对象的处理方法,参考如下代码

//创建一个九宫格数组 类似 3维数组  数组所有值用填充
let grids = new Array(9).fill(1);
console.log('grids', grids)

//将数组内重新填充
grids = grids.map((value,index) => value+index);
// grids.forEach((value,index) => grids[index]=value+index);
console.log('grids', grids)	

//将数组拼成一个字符串,用逗号分隔
let str = grids.join(',');
// let str = grids.toString();
console.log('str', str);

//将所有参数整理成数组
grids = Array.of('i',' ','l','o','v','e',' ','y','o','u');

str = grids.join('');
console.log('str', str);
console.log('value => array', grids);

//将字符串转换成数组
console.log('array', Array.from(str));
console.log('array', str.split(''));

//过滤掉数组中的空格符
grids = grids.filter((value,index) => value.trim()!='');
console.log('array filter', grids);

//判断数组中每项是否都符合条件
console.log('array space char', grids.every((value,index) => value!=' '));

//判断数组中某一项是否符合条件
console.log('array a space char', grids.some((value,index) => value==' '));

//按字母顺序排序
grids = grids.sort();
console.log('array sort', grids);

//原数组 反向排序
grids.reverse();
console.log('array reverse', grids);

//从数组索引起始处查找 符合条件的一条记录位置
console.log('array select where index', grids.indexOf('o'));
console.log('array select where index', grids.findIndex((value,index) => value=='o'));

//从数组索引末尾处查找 符合条件的一条记录位置
console.log('array select where index', grids.lastIndexOf('o'));

//截取数组中的一段
console.log('array ', grids.slice(3,5));

//连接两个数组
console.log('array conncat', grids.concat([1,2,3]));

//删除数组某项
grids.shift();//移除第一项
grids.pop();//移除最后一项
grids.splice(3,1);//移除第三个的一项
// grids.splice(3,1,'O');//替换第三个的一项
console.log('array ', grids);

//添加数组项
grids.unshift('Y');//添加到第一项
grids.push('E');//添加到最后一项
console.log('array ', grids);

2.非数组对象

关于非数组对象的处理,也可以叫JSON数据对象(数据结构中没有方法),参考代码如下

//定义一个对象
let args = {
	a: 1,
	b: 3,
	c: [],
	d: {},
	fun1: () => {}
};

//获取对象的所有属性名和方法名
console.log('object keys', Object.keys(args));

//获取对象的所有属性值和方法(匿名方法)
console.log('object values', Object.values(args));

//将对象的所有属性和方法通过键值对形式处理后返回
console.log('object entries', Object.entries(args));

//将JSON对象转换成字符串(其中方法类型被忽略)
console.log('object => json string', JSON.stringify(args));

//将JSON格式字符串转换成JSON对象
try{
	const json = `{"a":1,"b":3,"c":[],"d":{}}`;
	console.log('json string => object', JSON.parse(json));
}catch(err){
	//如果字符串JSON格式有误,转换可能会失败,然后抛出异常错误
	console.error(err)
}

3.引用对象

调用函数的时候,通过传递参数为对象的话,只能是传递对象的引用,参考如下代码

/**
 * 累加方法
 * @params { Object | Array | Numbers } 参数可以是对象,数组,多个数字
 * @return { Object | Number } 返回累加结果
 * */
function add(){
	if (arguments.length>0) {
		let args = arguments[0];
		//判断对象类型
		if (args instanceof Object) {
			//判断该对象是不是数组
			if (args instanceof Array) {
				//计算数组中的所有值,遍历数组,前后两个项参与计算
				return args.reduce((previous,current,args) => previous+current);
			}
			const { a, b } = args;
			args.c = a+b;
			return args;
		}
		let a = arguments[0] instanceof Number ? 0 : '';
		for(let i=0; i<arguments.length; i++) a+=arguments[i];
		return a;
	}
	throw new Error('没有传入可计算的参数')
}

// let args = [1,2,3];
// let res = add(args);
// console.log('res', res);

// console.log('calc', add(1,2,3,4));//调用方法,这里传递的参数是拷贝数值,返回计算后的结果
// console.log('calc', add('h','e','ll','o'));

//定义一个对象
let args = {
	a: 1,
	b: 3
};
//通过调用此方法可以看出,这里传递的参数是引用对象,调用后其对象的属性值c是计算后的结果
add(args);
console.log('args', args)

4.复制对象

JavaScript 有自带的拷贝函数,是Object.assign()方法,例子代码如下,注意这只能拷贝对象的自身属性和引用

let source = {
	a:1,
	b:'bb',
	c:{
		a:10,
		b:'bbb',
		c:{
			a:12
		},
		d:[1,2,3]
	}
};

let target = {
	a:2,
	d:4
};

//浅拷贝 target => source 非覆盖 只拷贝了数值和引用  不算全部复制
Object.assign(target,source);

console.log('source',source);
console.log('target',target);

target.b = 'cc';
target.c.a = 12;//这里是引用的 同时改变了source和target的值

console.log('source',source);
console.log('target',target);

JavaScript 没有自带的深度拷贝函数,下面通过自定义copyAll()方法以供调用,代码如下


/**
 * target => source 深度拷贝(全部复制过来)
 * @param { Object } target 当前对象
 * @param { Object } source 原对象
 * @param { Boolean } isReplace 是否覆盖
 * @return { Object } 返回拷贝出的对象
 * */
function copyAll(target,source,isReplace) {
	let isArray = source instanceof Array;
	if (target==undefined){
		if (isArray) target=[];
		else target={};
	}
	for(let i in source){
		if (isArray && i=='length') continue;
		if (isReplace && target[i]!=undefined) continue;
		switch(typeof source[i]){
			case 'object':
				target[i]=copyAll(target[i],source[i]);
				break;
			default:
				target[i]=source[i];
		}
	}
	return target;
}

//调用例子
let source = {
	a:1,
	b:'bb',
	c:{
		a:10,
		b:'bbb',
		c:{
			a:12
		},
		d:[1,2,3]
	}
};
				
let target = {
	a:3
};

copyAll(target,source,true);//深拷贝

target.b = 'cc';
target.c.a = 24;//以下 source的值 不受影响
target.c.c = 48;
target.c.d[1] = 33;

console.log('source',source);
console.log('target',target);

5.注意事项

💡小提示

  • 尝试修改对象值,要注意被其它引用后修改的影响,尽量用深度拷贝
  • 文章中提到对象的部分处理方法,JavaScript需要E5以上才支持

到此结束,如阅读中有遇到什么问题,请在结尾评论处留言,ヾ( ̄▽ ̄)ByeBye

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TA远方

谢谢!收到你的爱╮(╯▽╰)╭

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值