浅克隆

先看代码:

/**
* 浅克隆 克隆传入对象,只克隆一层
* @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. Python locals() 函数

    Python locals() 函数  Python 内置函数 描述 locals() 函数会以字典类型返回当前位置的全部局部变量. 对于函数, 方法, lambda 函式, 类, 以及实现了 __c ...

  2. jdeveloper基础教程(中文版)

    jdeveloper基础教程(中文版) 程序员的基础教程:菜鸟程序员

  3. 将对象转为json,加入到HttpResponseMessage中

    需要引用程序集: System.Net.Http System.Web System.Web.Extensions Code: using System; using System.Collectio ...

  4. cookie、session、token区分

    https://www.cnblogs.com/moyand/p/9047978.html http://www.cnblogs.com/JamesWang1993/p/8593494.html Co ...

  5. phalcon框架安装

    Phalcon学习笔记 - 安装 原创 2014年10月23日 12:20:33 标签: phalcon / phalcon安装 5014 如何学习一个新的框架 1  明白工作原理 2  知道核心思想 ...

  6. poj3017 Cut the Sequence 单调队列 + 堆 dp

    描述 把一个正数列 $A$分成若干段, 每段之和 不超过 $M$, 并且使得每段数列的最大值的和最小, 求出这个最小值. 题目链接 题解 首先我们可以列出一个$O(n^2)$ 的转移方程 : $F_i ...

  7. UDP接收数据

    http://blog.csdn.net/xingzheouc/article/details/49946191 http://blog.csdn.net/robertkun/article/deta ...

  8. 社交类APP原型模板分享——微信

    微信是一款社交类的APP应用——聊天软件,支持多人群聊. 交互效果主要有滚动内容界面.选择组件触发按钮状态变化.点击下拉展开列表.点击弹出面板等交互操作. 本原型由国产原型工具-Mockplus制作完 ...

  9. jquery和js中走的弯路

    1.$.each的错误用法 $.each的return xx 不能结束外层的函数,但return true/false可以 所以一般的: var result; $.each(json,functio ...

  10. js 数组去重的三种方法(unique)

    方法一: Array.prototype.unique=function(){ var arr=[];//新建一个临时数组 for(var i=0;i<this.length;i++){//遍历 ...