笔记——JS的对象复制

JS的对象复制——

Js的Number类型和String类型都不是地址引用,而是重新创建对象复制值;
var a = 1;
var b = a;
b = 2;
alert(a);
结果:1

var c = "abc";
var d = c;
d = "def";
alert(c);
结果:abc

只有对象类型才是地址引用的;
var a = {x:1};
var b = a;
b.x = 2;
alert(a.x);
结果:2

所以复制对象不要用“=”,而是遍历对象复制对象里的值,最好写个克隆方法

Jquery里有extend方法来复制对象
var objB = JQuery.extend(true, objA);

var objB = $.extend(true, objA);

var a = {xa:{y:1,z:"abc"},xb:{y:2,z:"def"}};
var b = jQuery.extend(true,a);
b.xb.y = 5;
alert(a.xb.y);
结果:1

但是,这时候a的类型是Object,b的类型是function?
typeof b
结果:"function"
typeof a
结果:"object"

alert(b)
结果:function (a,b){return new p.fn.init(a,b,c)}

也就是说,jQuery.extend返回的是方法本身的内存地址,b变量是指向方法的内存地址,虽然里面的值虽然是方法的return结果,但b变量并不代表一个Object
那么怎么让b连类型也复制过来呢?
b = $.clone(a);
TypeError: a.cloneNode is not a function
JQuery的克隆方法明显是克隆Dom节点的,并不能用于克隆对象

其实,只是extend方法没用好....T_T
var b = jQuery.extend(true,{},a);
在调用方法时传一个空对象为参数,extend就会将a对象的值复制给空对象,返回的就是对象,否则返回的就是方法,变量b实际指向内存地址就是传入空对象的内存地址,当然这时候已经不是空对象了。

如果没用JQuery,那自己写一个(从网上抄一个)也可以。
原理是利用递归将对象A里面的基础值一个一个复制,放到对象B里面对应参数名下就好了

下面是我自己写的test.js:

/*
author:lukelsq
Link:http://11163331.blog.51cto.com/
测试
var oldObj = {xa:{y:1,z:"abc"},xb:{y:2,z:"def"}};
var newObj = new Object(); 
myClone(newObj,oldObj);
*/
function myClone(n,o){
    var a;
    for(a in o){
        if(typeof(o[a]) == "object"){
            var t = new Object();
            n[a] = myClone(t,o[a]);
        } else {
            n[a] = o[a];
        }
    }
    return n;
}

测试环境FireFox 44.0.2,测试页面只引用了jquery-1.8.0.min.js和test.js

在网上查了很多资料,非常感谢分享者。

如有错误请指正,非常感谢!

时间: 2024-10-14 01:01:36

笔记——JS的对象复制的相关文章

JavaScript对象复制

近期项目因为怕数据污染所以用到了js的对象复制 js里的对象都是继承自object,是引用类型,所以无法通过=号复制 所以整理了一些常用的复制方法,如下 一.通过JSON序列化和反序列化创建新的对象 1 var obj = { a: 1, b: '2' }; 2 var newObj = JSON.parse(JSON.stringify(obj)); 测试一下: obj.a = 3;//obj和newObj指向了不同的引用,所以newObj的b属性并不会变化 console.log(newOb

Effective C++_笔记_条款12_复制对象时勿忘其每一个成分

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 编译器会在必要时候为我们的classes创建copying函数,这些“编译器生成版”的行为:将被烤对象的所有成员变量都做一份拷贝. 如果你声明自己的copying函数,意思就是告诉编译器你并不喜欢缺省实现中的某些行为.编译器仿佛被冒犯似的,会以一种奇怪的方式回敬:当你的实现代码几乎必然出错时却不告诉你.所以自己实现copying函数时,请遵循一条规则:如果你为c

JS对象复制

在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一个对象,如下代码: var i1 = 1; var i2 = i1; i2 = 2; alert("i1:"+i1+",i2:"+i2); 输出结果:i1:1 , i2:2 但可能没有发现,这种“复制”用在对象(object)类型是“错误”的,因为这只是把对象的地址复制

js中对象的复制,浅复制(浅拷贝)和深复制(深拷贝)

在js中,我们经常复制一个对象,复制数据,那么就会有人问了,怎么复制,今天鹏哥就带来js中的复制方法. JS中对象分为基本类型和复合(引用)类型,基本类型存放在栈内存,复合(引用)类型存放在堆内存. 堆内存用于存放由new创建的对象,栈内存存放一些基本类型的变量和对象的引用变量. 至于堆内存和栈内存的区别介绍,你们可以百度看看. 下面开始讲解复制: 这种只是简单的变量,内存小,我们直接复制不会发生引用. var a=123; var b=a; a=123456; alert(a); //1234

js数据类型隐式转换笔记以及js包装对象

“37”+7              //377 “37”-7              //30 巧用+/-规则  变字符串  x+''   变数字x-0 js里面的==是不严格等于 “123” == 123 0 == false nul l== undefined new  Object() == new Object() [1,2]==[1,2] 但是[1,2]===[1,2]是错的 因为比较的是对象的引用 ps: NaN值和任何东西比较都不相等 即便是不严格等于 ———————————

js面对对象编程(二):属性和闭包

上篇博客中讲解了一些js对象的基本概念和用法,这篇博客讲解一下js属性方面的:公有属性,私有属性,特权方法. 如果学过java,公有属性,私有属性,特权方法(即可以访问和设置私有属性的方法)一定很熟悉,那么让我们来看看在js里如何实现呢? 1.公有属性 首先看公有的第一层意思是可以被大家所访问的,对外开放的属性,是相对于私有属性而言的: function Person(name,age){ this.name=name; this.age=age; this.getName=function()

读书笔记 - js高级程序设计 - 第十五章 使用Canvas绘图

读书笔记 - js高级程序设计 - 第十三章 事件 canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好 有时候即使浏览器支持,操作系统如果缺缺乏必要的绘图驱动程序,则浏览器即使支持了也没用   <canvas> var drawing = document.getElementById("drawing"); if( drawing.getContext ){ drawing.getContext("2d"

JavaScript学习笔记——js变量的布尔值

typeof(1): numbertypeof(NaN): numbertypeof(Number.MIN_VALUE): numbertypeof(Infinity): numbertypeof("123"): stringtypeof(true): booleantypeof(window): objecttypeof(Array()): objecttypeof(function(){}): functiontypeof(document): objecttypeof(null)

JS 点击复制Copy插件--Zero Clipboard

写博客就是一周工作中遇到哪些问题,一个好处就是可以进行一个总结,另外一个好处就是下次遇到同样的问题即使那你记不住,也可以翻看你的博客解决了.同样也可以帮到别人遇到与你一样问题的人.或者别人有比你更好的解决办法,可以一起讨论,分析出更好的解决方法.所以这是个好习惯.既然是好习惯,那就得坚持. 但是想写好一篇博客好像不是那么容易的,因为你得有问题,不然你写什么,手放在键盘上不知道敲啥.或者是你自己主动学习了,对你的学习进行了总结.然后你得有得写. 这周公司同事分享的<贝叶斯方法>对我的感触挺大的.