【问题标题】:jQuery's (deep) extends bug?jQuery(深)扩展错误?
【发布时间】:2015-02-12 08:34:12
【问题描述】:

我正在尝试使用 jQuery 深度复制一个对象,但它无法提供一个完全独立的对象。

这是我的代码。

var copy = $.extend(true, {}, this);

然后当我比较两个对象时,我得到以下结果:

  • copy == this => false(到目前为止一切顺利)
  • copy.LstOptions == this.LstOptions => false(到目前为止一切顺利)
  • copy.LstOptions[0] == this.LstOptions[0] => 正确问题

LstOptions 不是原始类型,它实际上是一个对象数组。这是它的内容:

[{"ID":22,"Name":"man"},{"ID":27,"Name":"weird"},{"ID":25,"Name":"womanii"}]

为什么不被深拷贝,又如何被深拷贝?

Ps:这是我的全文:

{"changed":false,"data":null,"LstOptions":[{"ID":22,"Name":"man"},{"ID":27,"Name":"weird"},{"ID":25,"Name":"womanii"}],"NewRecord":null,"NewID":0,"done":false}

this 也有一些方法(构造函数),没有属性(get/setters)。

这是一个 JSFiddle https://jsfiddle.net/wk9e2kgn/1/,其中 console.log 输出 true,我希望它输出 false

【问题讨论】:

  • 那是对象,不是数组。只需将 json 用于您的情况。这本身就是滥用,extend 是为了扩展原型。
  • jQuery 的文档说:“在深度扩展中,对象和数组是扩展的,但是原始对象上的对象包装器......”
  • 无法重现:jsfiddle.net/o5hbd6f3 您确定LstOptions 包含您认为的内容吗? (如果数组为空,则您将 undefined 与 undefined 进行比较,这是真的。)
  • 我粘贴的 JSON 是在调用 var copy = $.extend(true, {}, this); 之后直接调用 JSON.stringify(this);
  • @simonzack 你如何建议我深度复制我的对象?使用 $.extend 是 SO 上最受欢迎的答案。

标签: jquery clone


【解决方案1】:

jQuery 不会对自定义对象类型的对象成员进行深度复制。

最好的解决办法可能是创建一个复制构造函数。

编辑: 我刚刚在构造函数的末尾添加了this.constructor = Object.prototype.constructor;,这使得 jQuery 的扩展深拷贝对象。

SpecialDataField.Options.Option = function (ref) {
    /**
    @type {int}
    */
    this.ID = 0;

    /**
    @type {?string}
    */
    this.Name = null;

    if (ref != null) {
        for (var v in this) {
            if (v in ref) {
                this[v] = ref[v];
            }
        }
    }

    this.constructor = Object.prototype.constructor;
}

【讨论】:

    【解决方案2】:

    jQuery 在您的示例中运行良好。我创建了一个 jsfiddle 来向您展示 jquery 正在使用 $.extend 制作您的对象的深层副本。我还通过更改值原始对象的属性对其进行了测试,但它不会影响复制对象的相同属性。

    我为此编写的代码如下:

    var original= {"changed":false,"data":null,"LstOptions":[{"ID":22,"Name":"man"},{"ID":27,"Name":"weird"},{"ID":25,"Name":"womanii"}],"NewRecord":null,"NewID":0,"done":false};
    
    // deep copy
    var copy = $.extend(true, {}, original);
    
    // compare objects which results false
    alert(original.LstOptions[0]==copy.LstOptions[0]);
    
    // change value
    original.LstOptions[0].Name="Ankush";
    
    // check same property of both objects
    alert(original.LstOptions[0].Name);
    alert(copy.LstOptions[0].Name);
    

    你可以在这里找到jsfiddle

    【讨论】:

    • 说“你的代码工作得很好”并不能帮助 OP 解决他们的问题。
    • OP 说 copy.LstOptions[0] == this.LstOptions[0] 这个语句返回 true 但不是那样,它返回 false。我也解释了我的答案。
    猜你喜欢
    • 2012-03-13
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多