对象常用的方法和对象的拷贝

对象方法

//Object.assign函数,第一个参数为目标对象,后面依次为源对象
//将来自一个或多个源对象中的值复制到一个目标对象
var first = {name : 'kong'};
var last = {age : 18};
var person = Object.assign(first, last);
console.log(person);
//{name : 'kong', age : 18},注意这里first因为是第一个参数会被当成目标对象,所以first自身属性也被更改为和person一样了,即first === person
//用于克隆对象
var clone = Object.assign({}, person);
//Object.freeze函数
//阻止修改现有属性的特性和值,并阻止添加新属性
var a = {name : 'kong', age : 18};
Object.freeze(a);
//此时不允许添加或修改a的任何属性
 
//Object.is函数
//用于判断两个值是否相同
Object.is(a, b);
//返回true或false
//注意,该函数与==运算符不同,不会强制转换任何类型,应该更加类似于===,但值得注意的是它会将+0和-0视作不同值
//Object.keys函数
//用于返回对象可枚举的属性和方法的名称
var a = {name : 'kong', age : 18, func : function(){}};
Object.keys(a);
//['name', 'age', 'func']
//Object.defineProperty函数
//将属性添加到对象,或修改现有属性的特性
var a = {};
Object.defineProperty(a, 'name', {
	value : 'kong',
	enumerable : true	//该属性是否可枚举
})
//与之对应的是Object.defineProperties函数,可添加多个属性
Object.defineProperties(a, {
	name : {
		value : 'kong',
		enumerable : true
	},
	job : {
		value : 'student',
		enumerable : true
	}
})

//hasOwnProperty方法
//确定某个对象是否具有带指定名称的属性,有的话返回true,否则false
//注意,该方法不会检查对象原型链中的属性
var s = new String('123');
console.log(s.hasOwnProperty('split'));			//false
console.log(String.prototype.hasOwnProperty('split'));		//true
 

//hasOwnProperty方法
//确定某个对象是否具有带指定名称的属性,有的话返回true,否则false
//注意,该方法不会检查对象原型链中的属性
var s = new String('123');
console.log(s.hasOwnProperty('split'));			//false
console.log(String.prototype.hasOwnProperty('split'));		//true
  

//isPrototypeOf方法
//确定一个对象是否存在于另一个对象的原型链中
function a(){
}
var b = new a();
console.log(a.prototype.isPrototypeOf(b));
//true

浅拷贝

浅拷贝的意思就是只复制引用(指针),而未复制真正的值。

const originArray = [1,2,3,4,5];
const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};

const cloneArray = originArray;
const cloneObj = originObj;

console.log(cloneArray); // [1,2,3,4,5]
console.log(originObj); // {a:'a',b:'b',c:Array[3],d:{dd:'dd'}}

cloneArray.push(6);
cloneObj.a = {aa:'aa'};

console.log(cloneArray); // [1,2,3,4,5,6]
console.log(originArray); // [1,2,3,4,5,6]

console.log(cloneObj); // {a:{aa:'aa'},b:'b',c:Array[3],d:{dd:'dd'}}
console.log(originArray); // {a:{aa:'aa'},b:'b',c:Array[3],d:{dd:'dd'}}

上面的代码是最简单的利用 = 赋值操作符实现了一个浅拷贝,可以很清楚的看到,随着 cloneArray 和 cloneObj 改变,originArray 和 originObj 也随着发生了变化。

深拷贝

JSON.stringify/parse的方法

const originArray = [1,2,3,4,5];
const cloneArray = JSON.parse(JSON.stringify(originArray));
console.log(cloneArray === originArray); // false
 
const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};
const cloneObj = JSON.parse(JSON.stringify(originObj));
console.log(cloneObj === originObj); // false
 
cloneObj.a = 'aa';
cloneObj.c = [1,1,1];
cloneObj.d.dd = 'doubled';
 
console.log(cloneObj); // {a:'aa',b:'b',c:[1,1,1],d:{dd:'doubled'}};
console.log(originObj); // {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};

确实是深拷贝,也很方便。但是,这个方法只能适用于一些简单的情况。比如下面这样的一个对象就不适用:

const originObj = {
  name:'axuebin',
  sayHello:function(){
    console.log('Hello World');
  }
}
console.log(originObj); // {name: "axuebin", sayHello: ƒ}
const cloneObj = JSON.parse(JSON.stringify(originObj));
console.log(cloneObj); // {name: "axuebin"}

undefined、function、symbol 会在转换过程中被忽略,如果对象中含有一个函数时(很常见),就不能用这个方法进行深拷贝

递归的方法

就是对每一层的数据都实现一次 创建对象->对象赋值 的操作

function deepClone(source){
  const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
  for(let keys in source){ // 遍历目标
    if(source.hasOwnProperty(keys)){
      if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
        targetObj[keys] = source[keys].constructor === Array ? [] : {};
        targetObj[keys] = deepClone(source[keys]);
      }else{ // 如果不是,就直接赋值
        targetObj[keys] = source[keys];
      }
    }
  }
  return targetObj;
}
const originObj = {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};
const cloneObj = deepClone(originObj);
console.log(cloneObj === originObj); // false
cloneObj.a = 'aa';
cloneObj.c = [1,1,1];
cloneObj.d.dd = 'doubled'; 
console.log(cloneObj); // {a:'aa',b:'b',c:[1,1,1],d:{dd:'doubled'}};
console.log(originObj); // {a:'a',b:'b',c:[1,2,3],d:{dd:'dd'}};

const originObj = {
  name:'axuebin',
  sayHello:function(){
    console.log('Hello World');
  }
}
console.log(originObj); // {name: "axuebin", sayHello: ƒ}
const cloneObj = deepClone(originObj);
console.log(cloneObj); // {name: "axuebin", sayHello: ƒ}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值