浅克隆

先看代码:

/**
* 浅克隆 克隆传入对象,只克隆一层
* @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;
}

深度克隆

代码:

/**
* 深克隆
*
* 示例:
* 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

测试执行速度:

javascript 对象克隆的更多相关文章

  1. JavaScript对象之深度克隆

    也不知道从什么时候开始,前端圈冒出了个新词:对象深度克隆.看起来好像很高大上的样子,实际上并不新鲜,在我们的实际项目开发中,你可能早已用到,只不过由于汉字的博大精深,有些原本很简单的事物被一些看似专业 ...

  2. javascript对象的深度克隆

    在做项目的时候需要向对象里面添加新属性,又不想修改原对象.于是就写: var newObj = oldObj,但是新对象属性改变后就对象也会跟着改变,这是因为无论是新对象还是旧对象,指向的内存地址都是 ...

  3. web前端学习(二) javascript对象和原型继承

    目录 1. JavaScrpt对象 2. 原型对象和继承 3. 对象的克隆 (1)javascript对象 在JS中,对象是属性的容器.对于单个对象来说,都由属性名和属性值构成:其中属性名需要是标识符 ...

  4. javascript深度克隆与javascript的继承实现

    1.javascript深度克隆: //注意这里的对象包括object和array function cloneObject(obj){ var o = obj.constructor === Arr ...

  5. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...

  6. JavaScript对象复制(一)(转载)

    在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...

  7. es6 javascript对象方法Object.assign()

    es6 javascript对象方法Object.assign() 2016年12月01日 16:42:34 阅读数:38583 1  基本用法 Object.assign方法用于对象的合并,将源对象 ...

  8. 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统

    面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...

  9. 初识JavaScript对象

    JavaScript对象语法.类型.属性 属性描述符(getOwnPropertyDescriptor().defineProperty()) [[Get]].[[Put]].Getter.Sette ...

随机推荐

  1. vortex

    vortex - Bing dictionary US['vɔr.teks]UK['vɔː(r)teks] n.旋涡:涡旋:低涡:感情(或局势)的旋涡 网络漩涡:涡流:旋风 变形Plural Form ...

  2. centos7,Python2.7安装request包

    1.安装epel扩展源:“sudo yum install epel-release” 2.安装python-pip:“sudo yum install python-pip” 3.升级pip:“su ...

  3. 25-删除m位数是剩下的最大

    /*                                    寻找最大数   题目内容: 请在整数 n 中删除m个数字, 使得余下的数字按原次序组成的新数最大,比如当n=92081346 ...

  4. adf 笔记

    1>jsf在bean中如何获取url参数,注意bean的范围,如果存在分页,范围不能设置为request,否则第二次加载的时候参数会为空. 最小设置为view,在当前页面中一直有效. 方法一:F ...

  5. Debian 使用 cron 执行定时任务

    在linux下有两种方法来让一个命令或者脚本执行: crontab : 执行一个任务一次或者多次. at : 只执行一次. crontab是通过读取一个crontab文件来工作,这是一个普通的文本文件 ...

  6. Mint UI 之 Swipe 组件

    #为什么不显示内容? 一定要指定 mt-swipe 元素的宽和高. <mt-swipe :auto="4000" class="swipe"> &l ...

  7. $.fn.extend 和$.extend函数

    区别和详解:jQuery extend()和jQuery.fn.extend()     首先是简单的概述区别:$.extend()是类方法   $.fn.extend()是原型方法   对象方法和原 ...

  8. XE4 for ios 谨慎处理字符串

    由于xe4 for ios  里面的字符串处理有变化,具体可以参考官方文档,这两天帮一个朋友调试ios 的 应用,由于没有注意这一块,折腾了很长时间.特此记录下来,希望其他人不要走弯路. 以下面代码为 ...

  9. 2018.09.27 codeforces618F. Double Knapsack(抽屉原理+构造)

    传送门 思维题. 考虑维护两个数列的前缀和a1,a2,a3,...,ana_1,a_2,a_3,...,a_na1​,a2​,a3​,...,an​和b1,b2,b3,...,bnb_1,b_2,b_ ...

  10. 树莓派安装mono

    http://www.mono-project.com/download/ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --r ...