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


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

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    5.注意事项

    💡小提示

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

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

  • 相关阅读:
    【Java多数据源实现教程】实现动态数据源、多数据源切换方式
    排序算法-冒泡排序
    【RocketMQ】【源码】Dledger日志复制源码分析
    深入浅出SSH
    ASEMI二极管1N4148(T4)的用途和使用建议
    【数据结构】树与二叉树
    Vue - 每个页面单独设置 body 背景色(独立修改单个页面的背景色,不同页面设置不同的背景颜色)
    高通 mtk 展讯等芯片机型读取 备份手机全字库分区 的一些操作解析
    【AIGC】如何在使用stable-diffusion-webui生成图片时看到完整请求参数
    怎样找外企/远程的工作
  • 原文地址:https://blog.csdn.net/zs1028/article/details/127692694