浅克隆

先看代码:

/**
* 浅克隆 克隆传入对象,只克隆一层
* @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. 常用修图工具的一些使用技巧及问题解决方法——ai

    一.ai如何修改画布大小 一. ai如何修改画布大小: 1. 左上角菜单中的文件——文档设置(也可以直接点菜单栏下边的控制栏中的文档设置) 2. 文档设置界面中,点击右上角“编辑画板“ 3. 此时面板 ...

  2. MYSQL错误:You can't specify target table for update in FROM clause

    这句话意思是:不能先select再更新(修改)同一个表. 可以再外嵌套多一层,这个问题只有mysql有,mssql和oracle都没有. # 出错delete from Person where Id ...

  3. Linux跑火车,提升趣味性

     實現跑火車[可陶冶情操,愉悦心情]##下载yum源[root@localhost ~]# wget http://mirror.centos.org/centos/7/extras/x86_64/P ...

  4. swift 设置图片动画组 iOS11之前 默认图片 设置不成功

    在iOS 11 上, 1.先执行动画组 在设置图片执行帧动画,2.先设置图片在设置帧动画,执行帧动画  没有任何问题 在iOS 10和iOS9上,必须 执行 方法二(先设置图片在设置帧动画,执行帧动画 ...

  5. 【JVM】浅谈双亲委派和破坏双亲委派

    一.前言 笔者曾经阅读过周志明的<深入理解Java虚拟机>这本书,阅读完后自以为对jvm有了一定的了解,然而当真正碰到问题的时候,才发现自己读的有多粗糙,也体会到只有实践才能加深理解,正应 ...

  6. Centos7下安装apache2.4 php5.6 pdo_oci oci8

    一.下载必须的安装源码包 http://httpd.apache.org/download.cgi#apache24 httpd-2.4.23.tar.gz http://apr.apache.org ...

  7. php iframe 上传文件

    我们通过动态的创建iframe,修改form的target,来实现无跳转的文件上传.   具体的实现步骤 1.捕捉表单提交事件 2.创建一个iframe 3.修改表单的target,指向iframe ...

  8. css设置超出部分文档隐藏(在table标签中不好使解决方案在下)

    css设置: .text-over{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;cursor: pointer} div设 ...

  9. 品味性能之道<三>:方法论

    自顶向下的性能优化方法论 系统优化是包括系统设计.开发.产品上线.平台优化的全过程,不同阶段的优化工作对全系统所带来的效益是不同的.理想的性能优化论应该采用自顶向下的优化方法,即在项目设计.开发和上线 ...

  10. css之颜色篇

      app多采用浅灰#f5f5f5   白色一般用white,如果觉得白太直接了,可以加一点点灰,#fefefe,   这种情况下搭配#e4e4e4的浅灰边框最合适.