这里用递归的思想进行 JS 对象的深度拷贝, 并进行封装, 思路如下
判断是不是原始值 使用方法: typeof()/object
判断是数组还是对象 使用方法: instanceof toString constructor
建立相应的数组或对象
循环递归
- function deepClone(origin,target){
- var target = target || {},
- toStr = Object.prototype.toString,
- arr = "[object Array]";
- for(var prop in origin){
- if(origin.hasOwnProperty(prop)){ // 选择自己的属性
- if(origin[prop] !== 'null' && typeof(origin[prop]) == 'object'){// 区分原始值和引用值
- if(toStr.call(origin[prop]) == arr){// 区分数组和对象
- target[prop] = [];// 建立数组
- }else{
- target[prop] = {};// 建立对象
- }
- deepClone(origin[prop],target[prop]); // 循环递归
- }else{
- target[prop] = origin[prop];
- }
- }
- }
- return target;
- }
代码可以将中间 target[prop] 赋值操作用三目运算符简化如下:
target[prop] = (toStr.call(origin[prop]) == arr) ? [] : {};
因此 简化后的深度拷贝的代码最后如下:
- function deepClone(origin,target){
- var target = target || {},// 容错
- toStr = Object.prototype.toString,//.call
- arr = "[object Array]";// 数组原型
- for(var prop in origin){
- if(origin.hasOwnProperty(prop)){// 判断是否是自己的属性
- if(origin[prop] !== 'null' && typeof(origin[prop]) == 'object'){// 判断引用值还是原始值
- target[prop] = (toStr.call(origin[prop]) == arr) ? [] : {};// 判断是数组还是对象 然后相应建立数组 / 对象
- deepClone(origin[prop], target[prop]);// 循环递归
- }else{// 原始值
- target[prop] = origin[prop];
- }
- }
- }
- return target;
- }
最后, 我们可以创建两个对象来进行深度拷贝
- var obj1 = {
- name : 'sunny',
- age : 100,
- sayName : function(){
- console.log(this.name);
- }
- }
- var obj2 = {};
执行拷贝
deepClone(obj1, obj2);// 放入源对象和拷贝对象
来源: http://www.qdfuns.com/note/51344/a4971605988888f77bf267a6a0371585.html