代码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的属性。 这位高手看看要怎么解决。。??

解决方案 »

  1.   

    先说代码1var 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([] === [])
      

  2.   


    代码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){ // 而不是用你的克隆对象实现
     }
      

  3.   

    或者你可以改变原型链// 删除test.m 以后
    del('m', test);// 改变test的原型链到默认Object上。。但是以后和obj就一点关系都没有了
    test.constructor.prototype = new Object();
    test.constructor = Object;
      

  4.   


    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;
    }
      

  5.   


    我用的是IE8的,我觉得test的contructor.prototype里面已经有个m属性了,删除掉之后,它会去找contructor.prototype.prototype里面的m属性,也就是obj的contructor.prototype里面的属性。验证如下:如果只删除掉obj的属性m,test的属性m还是存在的。
      

  6.   


    谢谢,代码可用。
    没想到slice函数居然可以连第一个参数都可以不用传。
      

  7.   

    "我觉得test的contructor.prototype里面已经有个m属性了,删除掉之后"
    你并没有删除掉 test.constructor.prototpe 的 属性
    你删除掉的是  test 的属性。delete test[pro] 不等于 delete test.constructor.prototype[pro]这两个删除操作的对象是不一样的。