浅克隆

先看代码:

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

    Python property() 函数  Python 内置函数 描述 property() 函数的作用是在新式类中返回属性值. 语法 以下是 property() 方法的语法: class pro ...

  2. [leetcode]403. Frog Jump青蛙过河

    A frog is crossing a river. The river is divided into x units and at each unit there may or may not ...

  3. ubuntu14.04安装opengl

    OpenGL 是一套由SGI公司发展出来的绘图函式库,它是一组 C 语言的函式,用于 2D 与 3D 图形应用程式的开发上. 不可或缺的就是编译器与基本的函式库,如果系统没有安装的话,依照下面的方式安 ...

  4. golang通过反射动态调用方法

    func Call(m map[string]interface{}, name string, params ...interface{}) ([]reflect.Value, error) { f ...

  5. db2 统计信息 runstats

    1.runstats的语法:runstats on table [模式名].[表名] with distribution and detailed indexes all注意:你可以在所有列上,或者仅 ...

  6. Codeforces 608B. Hamming Distance Sum 模拟

    B. Hamming Distance Sum time limit per test: 2 seconds memory limit per test:256 megabytes input: st ...

  7. Debian use sudo

    刚安装好的Debian默认还没有sudo功能.1.安装sudo# apt-get install sudo2.编辑 /etc/sudoers ,添加如下行# visudoroot ALL=(ALL:A ...

  8. part1:2-嵌入式系统简单概念

    1.3个特点+1个性质:以应用为中心.软硬件可裁剪.对功能-体积-功耗等有严格要求:专用的计算机系统. 应用领域: 软硬件可裁剪,是什么结构让嵌入式系统具备了这样的特点? 嵌入式系统的体系结构:硬件: ...

  9. cubieboard网络设置

    1.1 配置静态ip vi /etc/network/interface auto lo iface lo inet loopback #以下是添加的内如 auto eth0 #iface eth0 ...

  10. 冒泡排序java语言实现

    class bubbleSort { public static void main(String[] args){ int[] a={49,38,65,97,76,13,27,49,78,34,12 ...