JS数据类型分为两类: 基本类型(Number、Boolean、Undefined、Null、String、Symbol(ES6新加,此处不讨论))与引用类型(Object)。原始类型存储的是对象的实际数据,而对象类型存储的是对象的引用地址。

两种克隆

  1. 浅克隆: 原始类型为值传递,对象类型仍为引用传递。

  2. 深克隆: 所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。

浅克隆

1.对于基本类型:

//数值克隆
var a="1";
var b=a;
b="2";
console.log(a);// "1"
console.log(b);// "2"

2.对于引用类型:

我们都知道,函数在js中属于“一等公民”,同时也是引用类型,但是函数的克隆是通过浅克隆就可以实现,因为函数的克隆会在内存单独开辟一块空间,互不影响

var m=function(){alert(1);};
var n=m;
n=function(){alert(2);}; console.log(m());//1
console.log(n());//2

下面通过一段代码来看浅克隆的问题:

function clone(obj){
var result={};
for(key in obj){
result[key]=obj[key];
}
return result;
} var dog = {
name: '大黄',
age: 8,
hobby: {
food: 'cookie',
toy: 'ball'
}
} var oNew = clone(dog);
console.log(dog.hobby.food); // cookie
oNew.hobby.food = "icecream";
console.log(dog.hobby.food) // icecream

简单的复制对象,如果对象其中一个属性是引用型变量,就会出现这种情况,因为引用型变量保存的是内存地址,所以其实后来操作的都是同一块内存。

深克隆

1.JSON对象的parse和stringify

JSON对象是ES5中引入的新的类型(支持的浏览器为IE8+),JSON对象parse方法可以将JSON字符串反序列化成JS对象,stringify方法可以将JS对象序列化成JSON字符串,借助这两个方法,也可以实现对象的深复制。

var dog = {
name: '大黄',
age: 8,
hobby: {
food: 'cookie',
toy: 'ball'
}
} var oNew = JSON.parse(JSON.stringify(dog));
console.log(dog.hobby.food); // cookie
oNew.hobby.food = "icecream";
console.log(dog.hobby.food) // cookie

该方法的局限性:

  1. 无法复制函数

  2. 原型链没了,对象就是object,所属的类没了。

2.在jquery中extend方法可以用来扩展对象,这个方法可以传入一个参数:deep(true or false),表示是否执行深复制(如果是深复制则会执行递归复制),此处不细说。

3.自己定义

function deepClone(obj){
var result,
oClass=isClass(obj); if(oClass==="Object"){
result={};
}else if(oClass==="Array"){
result=[];
}else{
return obj;
}
for(key in obj){
var copy=obj[key];
if(isClass(copy)=="Object"){
result[key]=arguments.callee(copy);//递归调用
}else if(isClass(copy)=="Array"){
result[key]=arguments.callee(copy);
}else{
result[key]=obj[key];
}
}
return result;
}
//返回传递给他的任意对象的类
function isClass(o){
if(o===null) return "Null";
if(o===undefined) return "Undefined";
return Object.prototype.toString.call(o).slice(8,-1);
}

或者可以写为(只适用引用类型):

Object.prototype.clone = function(){

    var o = this.constructor === Array ? [] : {};

    for(var e in this){
o[e] = typeof this[e] === "object" ? this[e].clone() : this[e];
}
return o;
}

JavaScript的深克隆与浅克隆的更多相关文章

  1. Java克隆--深克隆与浅克隆的区别

    克隆,就是复制一个对象的副本,而克隆又分浅克隆和深克隆.浅克隆是指克隆得到的对象基本类型的值改变了,而源对象的值不会变.但如果被克隆对象引用类型的值改变了,那么源对象的值同样会改变,因为引用类型在栈内 ...

  2. 浅谈Java中的深克隆和浅克隆(阿里面试)

    在最近的秋招中,阿里和多益网络都问到了这个问题,虽然很简单,但是我还是想总结一下,感兴趣的可以看一下我的个人博客网站(Spring+MyBatis+redis+nginx+mysql)(适合菜鸟),最 ...

  3. Java中的深克隆和浅克隆

    为什么要克隆 首先思考一个问题, 为什么需要克隆对象? 直接new一个对象不行吗? 克隆的对象可能包含一些已经修改过的属性, 而new出来的对象的属性都还是初始化时候的值, 所以当需要一个新的对象来保 ...

  4. 【java开发系列】—— 深克隆和浅克隆

    Java支持我们对一个对象进行克隆,通常用在装饰模式和原型模式中.那么什么是深克隆,什么是浅克隆呢. [浅克隆],通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的. [深克隆],克隆的时候 ...

  5. JAVA深克隆与浅克隆1

    复制就是得到一个副本 克隆就是复制一个对象的复本.但一个对象中可能有基本数据类型,如:int,long,float    等,也同时含有非基本数据类型如(数组,集合等)被克隆得到的对象基本类型的值修改 ...

  6. js深克隆与浅克隆

    定义: 浅克隆: 克隆对象的一层属性, 如果对象还有对象的话,里面的对象没有进行克隆,只是把地址给了别人.也可以理解为只是简单的克隆了躯体,但是没有得到其灵魂: 深克隆:克隆对象的多层属性,对象里面还 ...

  7. javascript实现深克隆的几种方法

    1)普通函数实现 function cloneObject(obj) { if (obj === null || typeof obj !== 'object') { return obj; } va ...

  8. java深克隆与浅克隆

    2015.9.19 6:45   星期五    1

  9. java 深克隆(深拷贝)与浅克隆(拷贝)详解

    java深克隆和浅克隆 基本概念 浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所拷贝的对象,而不复制它所引用的对 ...

随机推荐

  1. PLSQL安装过程和SCOTT用户被锁的解决方法

    一.PLSQL安装: PLSQL基本就是一键式安装,没有什么需要修改的东西,一路Next就行了. 二.SCOTT用户被锁问题解决 1.问题如下: SCOTT用户默认是被锁的,需要通过system管理员 ...

  2. C# HTTP系列3 HttpWebRequest.ContentType属性

    系列目录     [已更新最新开发文章,点击查看详细] 获取或设置请求的 Content-type HTTP 标头的值.默认值为null. 常见的请求内容类型为以下几种: /// <summar ...

  3. netcore与ef资料收集

    http://www.cnblogs.com/cgzl/p/7661805.html https://www.cnblogs.com/cgzl/p/7675485.html https://www.c ...

  4. python接口自动化1-http协议简介

    前言 知道接口测试的小伙伴都应清楚http协议了,如果你还不清楚,那么接口测试做不好,自动化接口就更做不好了.那么做接口测试前先了解下http: HTTP协议(HyperText Transfer P ...

  5. Laravel关联模型中has和with区别

    本篇文章给大家带来的内容是关于Laravel关联模型中has和with区别(详细介绍),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 首先看代码: 1 2 3 4 5 6 $user ...

  6. Redis学习之zskiplist跳跃表源码分析

    跳跃表的定义 跳跃表是一种有序数据结构,它通过在每个结点中维持多个指向其他结点的指针,从而达到快速访问其他结点的目的 跳跃表的结构 关于跳跃表的学习请参考:https://www.jianshu.co ...

  7. 关于优秀的视频播放器 - PotPlayer

    播放器设置 直接截图: 其他重要功能 1. 切换语音:Alt + A 谢谢浏览!

  8. 【2】hexo+github搭建个人博客的简单使用

    使用hexo+github搭建一个可以外网访问的个人博客,此文用于记录博客初级的使用方法. 新建-编写-生成-部署文章的全过程 1.使用cmd完成 打开命令提示符[win+r输入cmd] 切换到自己本 ...

  9. EF Code first主从表,删除更新从表

    以order和orderItem为例,从表orderItem里有主表的orderId 想通过order.orderitems.add()或者remove()方法直接更新从表的话,必须在从表建立联合主键 ...

  10. 开源矿工工具箱新增了ETH反抽水工具

    开源矿工工具箱新增了ETH反抽水工具 —— 将决定使用Claymore挖ETH时拦截的老外的抽水归谁的权力交给矿工 众所周知,所有的挖矿辅助工具都拦截了老外的Claymore内核挖ETH时的内核开发费 ...