重温JS——对象的深拷贝(笔试题常考!)

目录

对象的深拷贝

一、对象深拷贝的引入

二、对象的深拷贝的两种方法  ——笔试题常考——背

三、对象的深拷贝的两种方法的讲解:


一、对象深拷贝的引入

对象属性们 Object.keys(obj1)返回数组装的obj1的所有成员名
var obj={name:"jack"},a="name";obj[a]可以取到"jack"

Object.prototype.copy1=function () {
    //设计代码 让它有如下功能
}
var obj={name:"karen",infos:[{img:"xx",count:20}]}
var obj2=obj.copy1()
obj2.infos[0].count=30
console.log(obj.infos[0].count)//30

var obj3=obj.copy1(true)
obj3.infos[0].count=40
console.log(obj.infos[0].count)//30
console.log(obj3.infos[0].count)//40

二、对象的深拷贝的两种方法  ——笔试题常考——背

(笔试题中经常出现-跟垂直水平居中频率差不多)——(标准答案)

方法1. 最简单的方式,缺陷是原型链没有拷贝 函数和null不会拷贝

var copy1 = function (obj) {
    return JSON.parse(JSON.stringify(obj));
}
var a = {a:function(){console.log('hello world')},b:{c:1},c:[1,2,3],d:"wanger",e:new Date(),f:null,g:undefined}
var b = copy1(a)

方法2.利用自调用

var copy1 = function (obj) { 
    if(obj === null) return null 
    if(typeof obj !== 'object') return obj;
    if(obj.constructor===Date) return new Date(obj); 
    if(obj.constructor === RegExp) return new RegExp(obj);
    var newObj = new obj.constructor ();  //保持继承链
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {   //不遍历其原型链上的属性
            var val = obj[key];
            newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合
        }
    }  
    return newObj;  
}; 
   var oldObj = {
            name: "karen",
            age: "20",
            arr1: [1, 2, 3],
            techer: {
                name: "jiang"
            }
        }
        function deepClone(obj) {
            if (typeof obj !== 'object' || obj == null) {
                return obj
            }
            if (obj.constructor === Date) return new Date(obj);
            if (obj.constructor === RegExp) return new RegExp(obj);
            var result
            if (obj instanceof Array) {  //数组
                result = []
            } else { //对象
                result = {}
            }
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) { //不遍历其原型链上的属性
                    result[key] = deepClone(obj[key])
                }
            }
            return result
        }
        var newObj = deepClone(oldObj)
        newObj.name = "jack"
        newObj.techer.name = "li"
        console.log(oldObj, newObj, newObj == oldObj)   

三、对象的深拷贝的两种方法的讲解:

对象深拷贝的方法一: 如果内部没有引用数据或者时间正则null等等数据时,使用此方法

		//想要结果是{name:"karen"}  false,有以下两种方法
			var obj={name:"karen"}			
			// var obj2={}
			// obj2.name=obj.name			
			var str=JSON.stringify(obj)//'{"name":"karen"}'	
		    var obj2=JSON.parse(str)//{name:"karen"}	
			console.log(obj2,obj==obj2)//{name:"karen"}  false

 对象深拷贝的方法二:上面的那个方法不能使用,就使用自己封装的方法 (第3个)

1、深拷贝是两者一模一样,但是不相等,所以以下就不是深拷贝。因为下面的类型不一样。

var obj={x1:null,x2:new Date(),x3:"hello",son:{age:20}}
var obj2=JSON.parse(JSON.stringify(obj))  //将obj对象转为字符串,再转为对象
console.log(obj2,obj)  //两者的x2也不同,obj2是用引号括起来的,而obj没有引号,它是一个对象

2、dt 和dt2不一样   dt2是字符串   dt是对象

var dt=new Date()
var dt2=JSON.parse(JSON.stringify(dt))
console.log(typeof dt2)   //string   

3、上面的 JSON.parse不能够实现深拷贝,下面就自己封装一个函数来实现深拷贝

注意:typeof(null) 是object

        var obj = {
            name: "karen",
            its: [10, 20, 30]
        } //[10,20,30,[90,100]]//null//"hello"//{x1:null,x2:new Date(),x3:"hello",son:{age:20}}
        var obj2 = new Person()
        function deepcopy(data) {
            if (typeof (data) == "object") {
                if (data.constructor == Date) {   //时间格式
                    return new Date(data.getTime())  //返回一个新的时间对象
                } else if (data == null) {    
                    return null
                } else if (data.constructor == RegExp) {   //正则表达式
                    return new RegExp(data)
                } else if (data.constructor == Array) {
                    var newArray = new Array()
                    for (var i = 0; i < data.length; i++) {
                        var temp = data[i]
                        newArray.push(arguments.callee(temp))  //函数的自调用
                    }
                    return newArray
                } else {
                    var newobj = new data.constructor() //构造函数,既可以拷贝成员,也不会让原型链上的方法丢失
                    // Object.keys()   //这个方法也可以遍历对象,和下面的 for in一样都可以实现遍历
                    for (var key in data) {
                        newobj[key] = arguments.callee(data[key])  //函数的自调用
                    }
                    return newobj
                }
            } else {
                return data
            }
        }
        var obj2 = deepcopy(obj)
        // console.log(obj2,obj==obj2,obj[3]==obj2[3])
        console.log(obj2, obj == obj2, obj.its == obj2.its)
   
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值