string转object对象_对象的克隆

7f6fcd26dce0a7d809f038d981ff32c5.png

​原创:牛津小马哥web前端工程师陈小妹妹。

63bb1ccaf2cc1897d0c99e3b51627ba5.png

应用场景:

在程序中,我们有时候需要将对象作为参数传递处理。有些人只是为了拿到对象的某些私有属性做一个数据处理,而有些人是为了拿到原型链上属性等等。如何拿到正确的对象来应用于这两个简单的情景呢?

这就是我们今天要讲的知识点,对象的深克隆和浅克隆

原生深克隆方法JSON.parse / stringify

这是一种会丢失某些数据的克隆方法。

如果你不使用Date,function,undefined,Infinity,正则表达式,Map集合,Set集合,Bolbs,FileLists,ImageDatas,稀疏数组sparse Arrays,类型化数组Typed Arrays或其他复杂类型的对象中,一个很简单的深克隆的对象方法就是:

JSON.parse(JSON.stringify(object))

以下为演示例子:

const a = {
  string: 'string',
  number: 123,
  bool: false,
  nul: null,
  date: new Date(),  // stringified
  undef: undefined,  // lost
  inf: Infinity,  // forced to 'null'
  re: /.*/,  // lost
}
console.log(a);
console.log(typeof a.date);  // Date object
const clone = JSON.parse(JSON.stringify(a));
console.log(clone);
console.log(typeof clone.date);  // result of .toISOString()

打印出结果如下

b8b4f845dd49d50e91218eafab89f2c6.png

f1bc8306a21c0e1bb9ed6de1f70de128.png

可以发现使用JSON.parse(JSON.stringify(object))丢失的数据类型比较多。所以在使用它的时候,我们需要清楚的知道目标对象object的数据类型。一般来说,如果我们需要处理的数据只有number,string,null类型,才推荐使用这个方法进行数据对象的克隆。

使用库进行深克隆

由于克隆对象并非易事(复杂类型,循环引用,函数等),因此大多数主要库都提供了克隆对象的功能。如果您已经在使用的库已经提供了克隆方法,你可以直接使用,大多数情况下库的克隆方法总比你自己写的完善得多。

lodash:_.cloneDeep方法

可以通过lodash.clonedeep模块单独导入,如果您尚未使用提供深度克隆功能的库,则可能是您的最佳选择

Example

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

AngularJS:angular.copy方法(Deep Copy)

angular.copy(source, [destination]);

jQuery:jQuery.extend(true, { }, oldObject);

<script>
var object1 = {
  apple: 0,
  banana: { weight: 52, price: 100 },
  cherry: 97
};
var object2 = {
  banana: { price: 200 },
  durian: 100
};

// Merge object2 into object1, recursively
$.extend( true, object1, object2 );

// Assuming JSON.stringify - not available in IE<8
$( "#log" ).append( JSON.stringify( object1 ) );
</script>

输出结果

{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}

jQuery还有一个.clone()的方法,仅克隆DOM元素。第一个参数为true,表示递归深层复制。这里不展开讨论。

ES6的浅克隆

为了完整起见,请注意ES6提供了两种浅表复制机制:Object.assign()和扩展运算符。

Object.assign()

语法:Object.assign(target, ...sources)

MDN上说了:

Object.assign()拷贝的是属性值。假如源对象sources的属性值是一个对象的引用,那么它也指向那个引用。

如果源对象的属性值为简单类型(string, number),通过Object.assign({},obj1);那么会得到这个属性值的独立拷贝;如果属性值为对象或其它引用类型,那么它会指向这个对象的引用。这是Object.assign()特别值得注意的地方。

let obj1 = { a: 0 , b: { c: 0}}; 
let obj2 = Object.assign({}, obj1); 
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} 

//源对象的属性值为简单类型
obj1.a = 1; 
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}} 
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} 

//源对象的属性值为引用类型
obj2.b.c = 3; 
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}} 
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 3}} 

扩展运算符

var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4); 

// arr2 此时变成 [1, 2, 3, 4]
// arr 不受影响

提示: 实际上, 展开语法和 Object.assign() 行为一致, 执行的都是浅拷贝(只遍历一层)。

关于对象的克隆的内容到此为止~感谢阅读!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值