JS使用JSON.parse(),JSON.stringify()实现对对象的深拷贝功能分析

发布网友

我来回答

2个回答

懂视网

本篇文章给大家带来的内容是关于JS对象浅克隆和深克隆的代码示例,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

浅克隆

先看代码:

/**
 * 浅克隆 克隆传入对象,只克隆一层
 * @param {any} source
 */
function shallowClone(source) {
 var tiaget = createEctype(source); //创建一个副本
 // 将原对象的所有属性值赋值到新对象上
 for (var property in source) {
 if (source.hasOwnProperty(property)) {
  tiaget[property] = source[property];
 }
 }
 /**
 * 创建副本
 * @param {any} source
 */
 function createEctype(source) {
 var newObject = {};
 if (Array.isArray(source))
  newObject = [];
 return newObject;
 }

 return tiaget;
}

执行测试:

var a={a1:1,a2:2,a3:[1,2,3]};
 var b={b1:1,b2:2,b3:[4,5,6]}
 a.b=b;
 b.a=a;
 a.a4=[a,b];
 b.b4=[a,b];
 a.fn=function(){console.log(this.b);};
 
 var newa=shallowClone(a);

测试代码定义了一个自我引用的对象

a===a.a4[0]; // true
a===a.b.a; // true

执行 shallowClone 方法获得了一个对象a的副本 newa

a === newa;  // false
newa === newa.a4[0]; // false
newa === newa.b.a; // false
a === newa.a4[0]; // true
a === newa.b.a;  // true

测试执行速度:

/**
获取传入方法在规定时间内执行次数

示例:
var test = function(){

};
runTime(test,1)
表示test方法 在1秒中执行了6819005次
**/

/**
 * 获取传入方法在规定时间内执行次数
 * @param {any} fn 执行的方法
 * @param {any} time 规定的时间,单位为秒
 */
function runTime(fn, time) {
 var startTime = Date.now();
 var count = 0;
 while (Date.now() - startTime < time * 1000) {
 fn.call();
 count++;
 }
 return count;
}

image

深度克隆

代码:

/**
 * 深克隆
 * 
 * 示例:
 * var a={a1:1,a2:2,a3:[1,2,3]};
 * var b={b1:1,b2:2,b3:[4,5,6]}
 * a.b=b;
 * b.a=a;
 * a.a4=[a,b];
 * b.b4=[a,b];
 * a.fn=function(){console.log(this.b);return this.b;};
 * 
 * var newa=deepClone(a);
 * newa.a1=123;
 * newa.fn();
 */
function deepClone(source) {
 this.objKeyCache = []; // 对象缓存
 this.objValueCache = []; // 对象克隆缓存

 this.clone = function (source) {
 var target = createEctype.call(this, source);
 for (var property in source) {
  if (source.hasOwnProperty(property)) {
  var value = source[property];
  if (typeof value === "number"
   || typeof value === "boolean"
   || typeof value === "symbol"
   || typeof value === "string"
   || typeof value === "function"
   || typeof value === "undefined"
   || value === null)
   target[property] = value;
  else if (typeof value === "object") {
   // 如果源对象在对象缓存中存在,就用对象克隆缓存中的值赋值
   var index = this.objKeyCache.indexOf(value);
   if (index >= 0)
   target[property] = this.objValueCache[index]; 
   else {
   target[property] = this.clone( value);
   }
  }
  else
   throw "未知数据类型" + (typeof value);
  }
 }

 return target;
 };
 /**
 * 创建副本
 * @param {any} source
 */
 function createEctype(source) {
 var target = {};
 if (Array.isArray(source))
  target = [];
 this.objKeyCache.push(source);
 this.objValueCache.push(target);
 return target;
 }
 var newObject = this.clone(source);
 // 释放缓存,防止内存溢出
 this.objKeyCache = [];
 this.objValueCache = [];
 return newObject;
}

执行测试:

var a={a1:1,a2:2,a3:[1,2,3]};
var b={b1:1,b2:2,b3:[4,5,6]}
a.b=b;
b.a=a;
a.a4=[a,b];
b.b4=[a,b];
a.fn=function(){console.log(this.b);return this.b;};

var newa=deepClone(a);
a === newa;  // false
newa === newa.a4[0] // true
newa === newa.b.a; // true
a === newa.a4[0]; // false
a === newa.b.a; // false

image

测试执行速度:

image

热心网友

本文实例讲述了JS使用JSON.parse(),JSON.stringify()实现对对象的深拷贝功能。分享给大家供大家参考,具体如下:
根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系。
测试例子:
var
test={
a:"ss",
b:"dd",
c:[
{dd:"css",ee:"cdd"},
{mm:"ff",nn:"ee"}
]
};
var
test1
=
JSON.parse(JSON.stringify(test));//拷贝数组,注意这行的拷贝方法
console.log(test);
console.log(test1);
test1.c[0].dd="change";
//改变test1的c属性对象的d属性
console.log(test);
//不影响test
console.log(test1);
测试结果:
根据测试结果,我们可以看到,test1已经从test复制一份,并且test1改变其中属性的值时,对原来的对象test没有造成影响。
JSON.parse(),JSON.stringify()兼容性问题
可以通过为IE7以及IE7以下版本的IE浏览器引入json2.js,使用json2.js来解决JSON的兼容性问题
<!--[if
lt
IE
7]>
<script
src="具体放路径/json2.js"></script>
<![endif]-->
json2.js的github地址为:https://github.com/douglascrockford/JSON-js
好了,到这里就实现了,使用JSON.parse(),JSON.stringify()对对象的深拷贝~~
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数*算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
您可能感兴趣的文章:JavaScript基于遍历操作实现对象深拷贝功能示例JavaScript对象的浅拷贝与深拷贝实例分析JavaScript
中对象的深拷贝js对象浅拷贝和深拷贝详解浅谈JavaScript中面向对象的的深拷贝和浅拷贝jQuery深拷贝Json对象简单示例JavaScript对象拷贝与赋值操作实例分析浅谈angularJs函数的使用方法(大小写转换,拷贝,扩充对象)JavaScript对象拷贝与Object.assign用法实例分析js实现数组和对象的深浅拷贝

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com