JavaScript对象克隆

雾桩索引
• 阅读 1822

前言

之前有人问我如何克隆一个JS对象,我当时没答上来;过后我查资料弄懂了这个问题,现在整理成文。

正文

JavaScript的一切实例都是对象,但他们也分为原始类型和引用类型。原始类型对象指的是字符串(String)、数值(Number)、布尔值(Boolean)、undefinednull,引用类型对象指的是数组(Array)、对象(Object)、函数(Function)。
既然对象分为这两类,他们的复制克隆也是有差别的。普通对象存储的是对象的实际数据,而引用对象存储的是对象的引用地址,而把对象的实际内容单独存放。下面我们就来看看他们克隆的区别。

原始类型对象的克隆

字符串的克隆

var x="abc";
var y=x;
y="xyz";
 
alert(x);   // "abc"
alert(y);   // "xyz"

数值的克隆

var x=1;
var y=x;
y=2;

alert(x);   // 1
alert(y);   // 2

布尔值的克隆

var x=true;
var y=x;
y=false;
 
alert(x);   // true
alert(y);   // false

我们可以看出来原始类型的克隆很简单,只需要一个=赋值就可以了;undefinednull也是同理。

引用类型的对象克隆

数值的克隆

如果采用普通克隆:

var x=[1,2];
var y=x;
y.push(3);

alert(x);   // 1,2,3
alert(y);   // 1,2,3

由上可知,原始数组x,克隆数组y,修改了克隆数组y,但也同时修改了原始数组x,这就是引用对象的特点。那么怎样才能达到完整的数组克隆呢?

var x=[1,2];
var y=[];
var i=0;
var j=x.length;
for(;i<j;i++){
    y[i]=x[i];
}
y.push(3);
 
console.log(x);   // [1,2]
console.log(y);   // [1,2,3]

这样,两个数值就互不干扰,实现了完整数组克隆。

对象的克隆

和数组的克隆同理,对象的完整克隆如下:

var x={a:2,b:4};
var y={};
var i;
for(i in x){
    y[i]=x[i];
}
y.c=6;
 
console.log(x);   // Object {a: 2, b: 4} 
console.log(y);   // Object {a: 2, b: 4, c: 6}

函数的克隆

var x=function(){alert(1);};
var y=x;
y=function(){alert(2);};

console.log(x);   // function(){alert(1);};
console.log(y);   // function(){alert(2);};

函数的克隆与原始类型对象克隆的方式类似;只需要使用=就可以了。

总结

根据上面的情况,另外,克隆引用对象必须采用完整克隆(深度克隆),包括对象的值也是一个对象也要进行完整克隆(深度克隆)。所以,我们可以总结并封装一个通用的克隆方法:

function clone(obj){
    var o,i,j,k;
    if(typeof(obj)!=="object" || obj===null)return obj;
    if(obj instanceof Array){
        o=[];
        i=0;j=obj.length;
        for(;i<j;i++){
            if(typeof(obj[i])==="object" && obj[i]!=null){
                o[i]=clone(obj[i]);
            }else{
                o[i]=obj[i];
            }
        }
    }else{
        o={};
        for(i in obj){
            if(typeof(obj[i])==="object" && obj[i]!==null){
                o[i]=clone(obj[i]);
            }else{
                o[i]=obj[i];
            }
        }
    }
    return o;
}

最后

这是我个人的博客,刚刚搭建好,欢迎大家来看看:Sunny的博客

点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Karen110 Karen110
4年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
凝雪探世界 凝雪探世界
4年前
js-Answers一
JavaScript的组成JavaScript由以下三部分组成:1.ECMAScript(核心):JavaScript语言基础2.DOM(文档对象模型):规定了访问HTML和XML的接口3.BOM(浏览器对象模型):提供了浏览器窗口之间进行交互的对象和方法JS的基本数据类型和引用数据类型
晴空闲云 晴空闲云
4年前
也谈JavaScript浅拷贝和深拷贝
网上关于这个话题,讨论有很多了,根据各路情况我自己整理了一下,最后还是能接近完美的实现深拷贝,欢迎大家讨论。javascript中的对象是引用类型,在复制对象的时候就要考虑是用浅拷贝还是用深拷贝。直接赋值对象是引用类型,如果直接赋值给另外一个对象,那么只是赋值一个引用,实际上两个变量指向的同一个数据对象,如果其中一个对象的属性变更,那么另外一个也会变更。示
Stella981 Stella981
4年前
JavaScript学习总结(十七)——Javascript原型链的原理
一、JavaScript原型链ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。在JavaScript中,用__proto__属性来表示一个对象的原型链。当查找一个对象的属性时,JavaScript会向上遍历原型
Stella981 Stella981
4年前
JavaScript的 基本数据类型
第一:Javascript对象是第二:Javascript中第三:Javascript的对象是数据;第四:JavaScript中的对象可以简单理解成"名称:值"对(name:value)。名称(name):"名称"部分是一个JavaScript字符串参考https://www
Stella981 Stella981
4年前
JavaScript Prototype
定义和用法prototype属性使您有能力向对象添加属性和方法。实例在本例中,将展示如何使用prototype属性来向对象添加属性:<scripttype"text/javascript"functionemployee(name,job,born){this.n
Stella981 Stella981
4年前
JVM调优总结一
数据类型   Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。基本类型包括:byte,short,int,long,cha
Wesley13 Wesley13
4年前
underscore.js 分析 第二天
Underscore源码中有这么句obj.lengthobj.length意思是typeofobj.lengthnumber,即检测obj的长度是否是数字我的理解:这么写是来检测一个对象数组的类型到底是数组还是对象。在Javascript中变量分为基本类型和引用类型,基本类型是Undefined、Null、Boo
Stella981 Stella981
4年前
Python 的可变类型与不可变类型(即为什么函数默认参数要用元组而非列表)
Python的内建标准类型有一种分类标准是分为可变类型与不可变类型:可变类型:列表、字典不可变类型:数字、字符串、元组因为变量保存的实际都是对象的引用,所以在给一个不可变类型(比如int)的变量a赋新值的时候,你实际上是在内存中新建了一个对象,并将a指向这个新的对象,然后将原对象的引用计数–1.比如下面的示例:
Stella981 Stella981
4年前
JVM调优总结(一)基本概念
数据类型Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。    基本类型:保存原始值,即:他代表的值就是数值本身;    引用类型:保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引