我们先看一下浅复制的缺陷,不知多少人中过招呢?
复制代码 代码如下:
var oOriginal = {
memNum: 1, // number
memStr: "I am a string", // string
memObj: {
test1: "Old value" // we'll test
},
memArr: [ // array
"a string", // string member of array
{ // object member of array
test2: "Try changing me" // we'll test
}
]
};
这是一个比较复杂的对象,对象包含着对象与数组。我们用Prototype著名的继承函数复杂一下。它那个东东实在很难说是继承,jQuery的也不算。
复制代码 代码如下:
var extend = function(result, source) {
for (var key in source)
result[key] = source[key];
return result;
}
测试程序:
复制代码 代码如下:
var oCopy = extend({},oOriginal); // 浅拷贝
oCopy.memObj.test1 = "New value"; // 出现问题了,会反射到原对象上
alert(oOriginal.memObj.test1); // 结果副本与原本都一同被修改了
oCopy.memArr[1].test2 = "I am changed";
alert(oOriginal.memArr[1].test2); // 同样中招了
[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]
看来如果不想修改原对象,我们需要特殊处理一下对象与数组。为了处理它们,我们就必须把它们识别出来。看下面函数:
复制代码 代码如下:
/**
* type identification - By 司徒正美::cheng (MIT Licensed)
* http://www.cnblogs.com/rubylouvre/archive/2010/01/20/1652646.html
*/
var is = function (obj,type) {
var toString = Object.prototype.toString,undefined;
return (type === "Null" && obj === null) ||
(type === "Undefined" && obj === undefined ) ||
toString.call(obj).slice(8,-1) === type;
};
上面的函数是用于进行类型识别的,typeof是不可靠的,Array会返回"object",instanceof也不行,它无法判定另一个文档对象的Array实例。利用Object.prototype.toString.call虽然不是尽善尽美,鸭子类型嘛,很容易仿造,但总比以前的靠谱多了。
下面正式进入主题,我们的深拷贝函数会特殊处理值为对象与数组的键值对,对于它们,程序会为目标对象先创建一个新对象与数组,然后再一层层拷下去。我们可以看到它并没有用hasOwnProperty,换言之,连原型中可遍历的属性都给它翻个底朝天。对于数组,我们不用for(,,,)循环,它只能循环括号中的元素,无法循环附在数组上的其他属性,因此这里还是需要for...in这个特慢的方法。由于深拷贝把所有属性都进行检测,中间还可能创建新对象,因此是个巨重型的方法。无事就别用。
复制代码 代码如下:
/**
* type identification - By 司徒正美::cheng (MIT Licensed)
* http://www.cnblogs.com/rubylouvre/archive/2010/03/26/1696600.html
*/
dom.deepCopy = function(result, source){
for(var key in source) {
var copy = source[key];
if(result === copy) continue;//如window.window === window,会陷入死循环,需要处理一下
if(dom.is(copy,"Object")){
result[key] = arguments.callee(result[key] || {}, copy);
}else if(dom.is(copy,"Array")){
result[key] = arguments.callee(result[key] || [], copy);
}else{
result[key] = copy;
}
}
return result;
};
[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]
作者:司徒正美
复制代码 代码如下:
var oOriginal = {
memNum: 1, // number
memStr: "I am a string", // string
memObj: {
test1: "Old value" // we'll test
},
memArr: [ // array
"a string", // string member of array
{ // object member of array
test2: "Try changing me" // we'll test
}
]
};
这是一个比较复杂的对象,对象包含着对象与数组。我们用Prototype著名的继承函数复杂一下。它那个东东实在很难说是继承,jQuery的也不算。
复制代码 代码如下:
var extend = function(result, source) {
for (var key in source)
result[key] = source[key];
return result;
}
测试程序:
复制代码 代码如下:
var oCopy = extend({},oOriginal); // 浅拷贝
oCopy.memObj.test1 = "New value"; // 出现问题了,会反射到原对象上
alert(oOriginal.memObj.test1); // 结果副本与原本都一同被修改了
oCopy.memArr[1].test2 = "I am changed";
alert(oOriginal.memArr[1].test2); // 同样中招了
[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]
看来如果不想修改原对象,我们需要特殊处理一下对象与数组。为了处理它们,我们就必须把它们识别出来。看下面函数:
复制代码 代码如下:
/**
* type identification - By 司徒正美::cheng (MIT Licensed)
* http://www.cnblogs.com/rubylouvre/archive/2010/01/20/1652646.html
*/
var is = function (obj,type) {
var toString = Object.prototype.toString,undefined;
return (type === "Null" && obj === null) ||
(type === "Undefined" && obj === undefined ) ||
toString.call(obj).slice(8,-1) === type;
};
上面的函数是用于进行类型识别的,typeof是不可靠的,Array会返回"object",instanceof也不行,它无法判定另一个文档对象的Array实例。利用Object.prototype.toString.call虽然不是尽善尽美,鸭子类型嘛,很容易仿造,但总比以前的靠谱多了。
下面正式进入主题,我们的深拷贝函数会特殊处理值为对象与数组的键值对,对于它们,程序会为目标对象先创建一个新对象与数组,然后再一层层拷下去。我们可以看到它并没有用hasOwnProperty,换言之,连原型中可遍历的属性都给它翻个底朝天。对于数组,我们不用for(,,,)循环,它只能循环括号中的元素,无法循环附在数组上的其他属性,因此这里还是需要for...in这个特慢的方法。由于深拷贝把所有属性都进行检测,中间还可能创建新对象,因此是个巨重型的方法。无事就别用。
复制代码 代码如下:
/**
* type identification - By 司徒正美::cheng (MIT Licensed)
* http://www.cnblogs.com/rubylouvre/archive/2010/03/26/1696600.html
*/
dom.deepCopy = function(result, source){
for(var key in source) {
var copy = source[key];
if(result === copy) continue;//如window.window === window,会陷入死循环,需要处理一下
if(dom.is(copy,"Object")){
result[key] = arguments.callee(result[key] || {}, copy);
}else if(dom.is(copy,"Array")){
result[key] = arguments.callee(result[key] || [], copy);
}else{
result[key] = copy;
}
}
return result;
};
[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]
作者:司徒正美
标签:
javascript,深拷贝
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
桃源资源网 Design By www.nqtax.com
暂无“javascript 深拷贝”评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。