对象深拷贝后删除属性问题??

llyy112233 2011-03-25 10:50:38
代码1 :



<script type="text/javascript">
//对象深拷贝函数
var cloneAll = function (o){
function clonePrototype(){}
clonePrototype.prototype = o;
var obj = new clonePrototype();
for(var elements in obj){
if (typeof(obj[elements]) == "object") {
obj[elements] = cloneAll(obj[elements]);
}
}
return obj;
}

var obj = {
m : {o : {l : 1}, p : 1},
n : 2
}

var test = cloneAll(obj);

function del(attr, o) {
delete o[attr];
}


del('m', test);

for (var attr in test) {
alert('test : ' + attr + ' ' + test[attr]);
}

del('m', obj);

for (var attr in obj) {
alert('obj : ' + attr + ' ' + obj[attr]);
}


</script>




代码2 ,换一下删除的顺序:


<script type="text/javascript">
var cloneAll = function (o){
function clonePrototype(){}
clonePrototype.prototype = o;
var obj = new clonePrototype();
for(var elements in obj){
if (typeof(obj[elements]) == "object") {
obj[elements] = cloneAll(obj[elements]);
}
}
return obj;
}

var obj = {
m : {o : {l : 1}, p : 1},
n : 2
}

var test = cloneAll(obj);

function del(attr, o) {
delete o[attr];
}

del('m', obj);

for (var attr in obj) {
alert('obj : ' + attr + ' ' + obj[attr]);
}

del('m', test);

for (var attr in test) {
alert('test : ' + attr + ' ' + test[attr]);
}

</script>



代码1和代码2在IE中表现均正常,但是在chrome中却变现得很奇怪。

代码1先删除复制的对象test的属性m没有删除掉,但源对象obj的m却删除掉了。 这是为什么????

代码2先删除源对象obj的m后,test的m也正常删除了。。

要的效果就是不动obj对象,在chrome中删除掉 test的属性。

这位高手看看要怎么解决。。??
...全文
314 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
llyy112233 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 firebugdotname 的回复:]
"我觉得test的contructor.prototype里面已经有个m属性了,删除掉之后"


你并没有删除掉 test.constructor.prototpe 的 属性
你删除掉的是 test 的属性。

delete test[pro] 不等于 delete test.constructor.prototype[pro]

这两个删除操作的对象是不一样的。
[/Quote]

确实不一样,谢谢, 问题已解决。
firebugdotname 2011-03-26
  • 打赏
  • 举报
回复

function deepClone(obj){
var result = {};

for(var p in obj){
if(obj[p] instanceof Array){
result[p] = obj[p].slice();
continue;
}

if(obj[p] && typeof obj[p] == "object"){
result[p] = arguments.callee.call(null, obj[p]);
continue;
}

result[p] = obj[p];
}

return result;
}

firebugdotname 2011-03-26
  • 打赏
  • 举报
回复
先说代码1



var b = {name: 'ethan'};
var a = cloneAll(b)
//代码执行到这里的时候, 对象b成为对象a构造函数的原型链
// clonePrototype.prototype = o;
// var obj = new clonePrototype();
// 由这两行代码实现





delete a.name
//删除对象a的name属性 (其实对象a本身不存在name属性,name属性存在于a的构造函数原型中,即对象b)




alert(a.name)
//查询对象a的name属性,没找到,于是去对象a构造函数的原型(即b)中查询,找到name属性,返回'ethan';



至于楼主说的在ie中的行为和chrome中不大一样我手上只有ie9,测试的结果是一样。不知道你用的是什么版本的IE。



代码2中,先删除了原型的属性,所以在实例对象上没有找到该属性,这个行为也是预料之中的。



example:

function F(){}
F.prototype = {list: []}

alert((new F).list === (new F).list)
alert([] === [])

firebugdotname 2011-03-26
  • 打赏
  • 举报
回复
"我觉得test的contructor.prototype里面已经有个m属性了,删除掉之后"


你并没有删除掉 test.constructor.prototpe 的 属性
你删除掉的是 test 的属性。

delete test[pro] 不等于 delete test.constructor.prototype[pro]

这两个删除操作的对象是不一样的。
llyy112233 2011-03-26
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 firebugdotname 的回复:]
JScript code

function deepClone(obj){
var result = {};

for(var p in obj){
if(obj[p] instanceof Array){
result[p] = obj[p].slice();
continue;
……
[/Quote]

谢谢,代码可用。
没想到slice函数居然可以连第一个参数都可以不用传。
llyy112233 2011-03-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hnxxwyq 的回复:]
JScript code

代码1
// 理解当前object和原型链的关系,好像 你父亲的钱 和 你的钱
del('m', test);

// 你的钱花完了,不代表你父亲的钱花完了

for (var attr in test) {
alert('test : ' + attr + ' ' + test[attr]);
}

// 你父亲的钱也花完了……
[/Quote]

比喻得很形象,谢谢。
我没有考虑到原型链继承的问题。 学习了。
llyy112233 2011-03-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 firebugdotname 的回复:]
先说代码1


JScript code


var b = {name: 'ethan'};
var a = cloneAll(b)
//代码执行到这里的时候, 对象b成为对象a构造函数的原型链
// clonePrototype.prototype = o;
// var obj = new clonePrototype();
// 由这两行代码实现





……
[/Quote]

我用的是IE8的,我觉得test的contructor.prototype里面已经有个m属性了,删除掉之后,它会去找contructor.prototype.prototype里面的m属性,也就是obj的contructor.prototype里面的属性。

验证如下:如果只删除掉obj的属性m,test的属性m还是存在的。
lazyboy_wu 2011-03-26
  • 打赏
  • 举报
回复
或者你可以改变原型链



// 删除test.m 以后
del('m', test);

// 改变test的原型链到默认Object上。。但是以后和obj就一点关系都没有了
test.constructor.prototype = new Object();
test.constructor = Object;
lazyboy_wu 2011-03-26
  • 打赏
  • 举报
回复

代码1
// 理解当前object和原型链的关系,好像 你父亲的钱 和 你的钱
del('m', test);

// 你的钱花完了,不代表你父亲的钱花完了

for (var attr in test) {
alert('test : ' + attr + ' ' + test[attr]);
}

// 你父亲的钱也花完了,你们家开始穷了
del('m', obj);

for (var attr in obj) {
alert('obj : ' + attr + ' ' + obj[attr]);
}


// 代码2

// 你父亲的钱没有了,仅代表你不能再继承你父亲的家产了
del('m', obj);

for (var attr in obj) {
alert('obj : ' + attr + ' ' + obj[attr]);
}

// 你的钱花完了 又不能从你父亲那里拿钱,只能受穷了
del('m', test);

for (var attr in test) {
alert('test : ' + attr + ' ' + test[attr]);
}

// 你觉得你既然是你父亲的儿子,你花完钱了,那么(在你父亲有钱的前提下)你不想继承你父亲的钱,这合理吗?
// 答案很简单,只要你不是你父亲的儿子就可以实现
// 同理,只要不用原型链,仅对象复制可以实现你要的效果
for(var elements in o){ // 而不是用你的克隆对象实现
}
内容概要:本文系统研究了在强弱电网适配场景下,构网型(GFM)与跟网型(GFL)逆变器并联系统的协同控制逻辑及其暂态动态行为,重点依托Simulink仿真平台构建混合并网系统模型,深入分析两类逆变器在不同电网强度条件下的交互特性、频率响应机制、稳定性表现及抗扰能力。研究涵盖分层控制架构设计、异构控制策略对比、频率扰动响应规律以及多工况暂态性能评估,探讨了GFM与GFL逆变器在功率支撑、电压频率调节和系统稳定性方面的互补性与协同机制,旨在提升高比例新能源接入背景下并网系统的适应性、鲁棒性与动态性能。; 适合人群:具备电力电子、新能源并网、自动控制或电力系统仿真等相关专业知识背景,从事新型电力系统控制、微电网运行、逆变器控制策略研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①深入理解构网型与跟网型逆变器在强弱电网中的协同工作机理与动态交互特性;②掌握异构逆变器并联系统的建模方法、协同控制策略设计与暂态仿真分析流程;③为高渗透率新能源系统的稳定性分析、控制优化及工程应用提供理论依据和技术参考。; 阅读建议:建议结合Simulink仿真实例进行动手实践,重点关注控制策略的实现细节、参数整定方法及多工况仿真结果的动态响应分析,同时可参考文中提及的相关博士论文复现案例以深化对理论机制的理解。

87,988

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧