js对象浅拷贝和深拷贝详解


Posted in Javascript onSeptember 05, 2016

本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下

1.浅拷贝

拷贝就是把父对像的属性,全部拷贝给子对象。

下面这个函数,就是在做拷贝:

var Chinese = {
nation:'中国'
}
var Doctor = {

career:'医生'
}

function extendCopy(p) {


var c = {};


for (var i in p) { 



c[i] = p[i];


}


c.uber = p;


return c;
 }

使用的时候,这样写:

var Doctor = extendCopy(Chinese);
Doctor.career = '医生';
alert(Doctor.nation); // 中国

但是,这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。

请看,现在给Chinese添加一个”出生地”属性,它的值是一个数组。

Chinese.birthPlaces = ['北京','上海','香港'];

通过extendCopy()函数,Doctor继承了Chinese。

var Doctor = extendCopy(Chinese);

然后,我们为Doctor的”出生地”添加一个城市:

Doctor.birthPlaces.push('厦门');

看一下输入结果

alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
alert(Chinese.birthPlaces); //北京, 上海, 香港, 厦门

结果是两个的出生地都被改了。

所以,extendCopy() 只是拷贝了基本类型的数据,我们把这种拷贝叫做“浅拷贝”。

2.深拷贝

因为浅深拷有如此弊端所以我们接下来看一下深拷贝

所谓”深拷贝”,就是能够实现真正意义上的数组和对象的拷贝。它的实现并不难,只要递归调用”浅拷贝”就行了。

function deepCopy(p, c) {

var c = c || {};


for (var i in p) {



if (typeof p[i] === 'object') {




c[i] = (p[i].constructor === Array) ? [] : {};




deepCopy(p[i], c[i]);



} else {




 c[i] = p[i];



}


}


return c;

}

看一下使用方法:

var Doctor = deepCopy(Chinese);

现在,给父对象加一个属性,值为数组。然后,在子对象上修改这个属性:

Chinese.birthPlaces = ['北京','上海','香港'];
Doctor.birthPlaces.push('厦门');

alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
alert(Chinese.birthPlaces); //北京, 上海, 香港

这样就完成了拷贝;

$.extend()

jquery 中$.extend()如同。

$.extend( [deep ], target, object1 [, objectN ] )

 •deep
类型: Boolean
如果是true,合并成为递归(又叫做深拷贝)。
 •target
类型: Object
对象扩展。这将接收新的属性。
 •object1
类型: Object
一个对象,它包含额外的属性合并到第一个参数.
 •objectN
类型: Object
包含额外的属性合并到第一个参数 

当我们提供两个或多个对象给$.extend(),对象的所有属性都添加到目标对象(target参数)。

如果只有一个参数提供给$.extend(),这意味着目标参数被省略。在这种情况下,jQuery对象本身被默认为目标对象。这样,我们可以在jQuery的命名空间下添加新的功能。这对于插件开发者希望向 jQuery 中添加新函数时是很有用的。

请记住,目标对象(第一个参数)将被修改,并且将通过$.extend()返回。然而,如果我们想保留原对象,我们可以通过传递一个空对象作为目标对象:

var object = $.extend({}, object1, object2);

在默认情况下,通过$.extend()合并操作不是递归的;如果第一个对象的属性本身是一个对象或数组,那么它将完全用第二个对象相同的key重写一个属性。这些值不会被合并。可以通过检查下面例子中 banana 的值,就可以了解这一点。然而,如果将 true 作为该函数的第一个参数,那么会在对象上进行递归的合并。

警告:不支持第一个参数传递 false 。

1. 合并两个对象,并修改第一个对象。

var object1 = {
 apple: 0,
 banana: { weight: 52, price: 100 },
 cherry: 97
};
var object2 = {
 banana: { price: 200 },
 durian: 100
};

// Merge object2 into object1
$.extend( object1, object2 );

// Assuming JSON.stringify - not available in IE<8
console.log( JSON.stringify( object1 ) );
//{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}

2. 采用递归方式合并两个对象,并修改第一个对象。

var object1 = {
 apple: 0,
 banana: { weight: 52, price: 100 },
 cherry: 97
};
var object2 = {
 banana: { price: 200 },
 durian: 100
};

// Merge object2 into object1, recursively
$.extend( true, object1, object2 );

// Assuming JSON.stringify - not available in IE<8
console.log( JSON.stringify( object1 ) );
//{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}

3. 合并 defaults 和 options 对象,并且不修改 defaults 对象。这是常用的插件开发模式。

var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };

// Merge defaults and options, without modifying defaults
var settings = $.extend( {}, defaults, options );


console.log(JSON.stringify( defaults ));
console.log(JSON.stringify( options ));
console.log(JSON.stringify( settings ));
//defaults -- {"validate":false,"limit":5,"name":"foo"}
//options -- {"validate":true,"name":"bar"}
//settings -- {"validate":true,"limit":5,"name":"bar"}

Javascript 判断对象是否相等

在Javascript中相等运算包括”==”,”===”全等,两者不同之处,不必多数,本篇文章我们将来讲述如何判断两个对象是否相等? 你可能会认为,如果两个对象有相同的属性,以及它们的属性有相同的值,那么这两个对象就相等。那么下面我们通过一个实例来论证下:

var obj1 = {
  name: "Benjamin",
  sex : "male"
}

var obj2 = {
  name: "Benjamin",
  sex : "male"
}

//Outputs: false
console.log(obj1 == obj2);

//Outputs: false
console.log(obj1 === obj2);

通过上面的例子可以看到,无论使用”==”还是”===”,都返回false。主要原因是基本类型string,number通过值来比较,而对象(Date,Array)及普通对象通过指针指向的内存中的地址来做比较。看下面一个例子:

var obj1 = {
  name: "Benjamin",
  sex : "male"
};

var obj2 = {
  name: "Benjamin",
  sex : "male"
};

var obj3 = obj1;

//Outputs: true
console.log(obj1 == obj3);

//Outputs: true
console.log(obj1 === obj3);

//Outputs: false
console.log(obj2 == obj3);

//Outputs: false
console.log(obj2 === obj3);

上例返回true,是因为obj1和ob3的指针指向了内存中的同一个地址。和面向对象的语言(Java/C++)中值传递和引用传递的概念相似。 因为,如果你想判断两个对象是否相等,你必须清晰,你是想判断两个对象的属性是否相同,还是属性对应的值是否相同,还是怎样?

function person(name) { 
  this.name=name; 
} 

var p1 = new person("p1"); 
var p2 = new person("p2"); 

console.log(p1 == p2); //false 

person.prototype.sayHi = function() { 
  // do sayHi here 
} 

console.log(p1.sayHi() == p2.sayHi()); //true 
console.log(p1.sayHi() === p2.sayHi()); //true

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript Event学习第五章 高级事件注册模型
Feb 07 Javascript
JS 按钮点击触发(兼容IE、火狐)
Aug 07 Javascript
js重写alert控件(适合学习js的新手朋友)
Aug 24 Javascript
jQuery焦点图插件SaySlide
Dec 21 Javascript
微信小程序 video详解及简单实例
Jan 16 Javascript
js实现下拉菜单效果
Mar 01 Javascript
Bootstrap 3浏览器兼容性问题及解决方案
Apr 11 Javascript
vue项目中引入noVNC远程桌面的方法
Mar 05 Javascript
nuxt框架中路由鉴权之Koa和Session的用法
May 09 Javascript
JavaScript实现省市联动效果
Nov 22 Javascript
vue-router 2.0 跳转之router.push()用法说明
Aug 12 Javascript
node.js 如何监视文件变化
Sep 01 Javascript
JS实现隐藏同级元素后只显示JS文件内容的方法
Sep 04 #Javascript
jQuery实现智能判断固定导航条或侧边栏的方法
Sep 04 #Javascript
angularjs实现文字上下无缝滚动特效代码
Sep 04 #Javascript
jQuery实现为LI列表前3行设置样式的方法【2种方法】
Sep 04 #Javascript
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
Sep 04 #Javascript
jQuery实现的自动加载页面功能示例
Sep 04 #Javascript
jQuery简单实现中间浮窗效果
Sep 04 #Javascript
You might like
简单的php 验证图片生成函数
2009/05/21 PHP
curl不使用文件存取cookie php使用curl获取cookie示例
2014/01/26 PHP
php获得网站访问统计信息类Compete API用法实例
2015/04/02 PHP
php实现微信扫码自动登陆与注册功能
2016/09/22 PHP
PHP如何实现订单的延时处理详解
2017/12/30 PHP
Ubuntu上安装yaf扩展的方法
2018/01/29 PHP
PHP实现打包zip并下载功能
2018/06/12 PHP
PHP 出现 http500 错误的解决方法
2021/03/09 PHP
PNG背景在不同浏览器下的应用
2009/06/22 Javascript
jQuery.autocomplete 支持中文输入(firefox)修正方法
2011/03/10 Javascript
JS判断两个时间大小的示例代码
2014/01/28 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
2015/09/04 Javascript
javascript实现五星评分功能
2015/11/10 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
2016/01/04 Javascript
jQuery焦点图轮播插件KinSlideshow用法分析
2016/06/08 Javascript
KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定
2016/10/10 Javascript
微信小程序  网络请求API详解
2016/10/25 Javascript
Angular工具方法学习
2016/12/26 Javascript
JavaScript评论点赞功能的实现方法
2017/03/13 Javascript
[59:44]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 paiN vs iG
2018/03/31 DOTA
使用C语言扩展Python程序的简单入门指引
2015/04/14 Python
Python的装饰器用法学习笔记
2016/06/24 Python
python自动化报告的输出用例详解
2018/05/30 Python
python关于矩阵重复赋值覆盖问题的解决方法
2019/07/19 Python
Django中使用MySQL5.5的教程
2019/12/18 Python
Python简单实现区域生长方式
2020/01/16 Python
Supersmart英国:欧洲市场首批食品补充剂供应商之一
2018/05/05 全球购物
美国滑雪板和装备购物网站:Skis.com
2018/12/20 全球购物
校园门卫岗位职责
2013/12/09 职场文书
2014最新实习证明模板
2014/10/02 职场文书
机关作风建设工作总结
2014/10/23 职场文书
2014年化验员工作总结
2014/11/18 职场文书
自信主题班会
2015/08/14 职场文书
2016毕业实习单位评语大全
2015/12/01 职场文书
OpenCV 图像梯度的实现方法
2021/07/25 Python
Python+Matplotlib+LaTeX玩转数学公式
2022/02/24 Python