jQuery.extend是否不受循环引用的影响?

时间:2011-12-02 11:22:47

标签: javascript recursion merge circular-reference cloning

jQuery.extend安全circular reference吗?

如何在Javascript中避免循环引用(同时克隆或检查递归)?仅检查其属性列表中是否存在当前目标是不够的,因为它可能引用某些外部对象。

一个选项是保留到目前为止所有objects的另一个列表。但是会增加内存消耗并要求停止脚本吗?

我不想在工作线程中移动克隆操作。

1 个答案:

答案 0 :(得分:0)

古老的问题,但我今天正在寻找-答案是:否。

https://api.jquery.com/jquery.extend/

  

在深度扩展中,对象和数组得到了扩展,但是原始类型的对象包装器   例如String,Boolean和Number则不是。 深度扩展循环数据结构   将导致错误

     

对于超出此行为范围的需求,请编写自定义扩展   而是使用方法,或使用lodash之类的库。

lodash文档不是很清楚,但是_.cloneDeep支持克隆循环引用。

https://lodash.com/docs/4.17.10#cloneDeep

最好使用lodash之类的工具,因为我认为它将正确地检测所有不止一次引用的所有对象,并创建完整的对象图的真实克隆,并完整保留所有循环引用。

但是,这是一个幼稚的深层克隆,它使用简单的对象堆栈(在TypeScript中)简单地忽略了循环引用:

public static DeepClone(source: any, stack: any[] = null): any
{
    if (!source)
    {
        return source;
    }

    var result;

    result = Array.isArray(source) ? [] : {};

    for (var k in source)
    {
        var v = source[k];
        if (typeof v === "object") 
        {
            stack = stack || [];

            // Just ignore circular references? Or, to be clever, maintain a 
            // dictionary of object references from the original graph linked to
            // the new objects in the cloned graph, to preserve the full graph.
            if (stack.indexOf(source) >= 0)
            {
                return null;
            }

            stack.push(source);

            result[k] = this.DeepClone(v, stack);

            stack.pop();
        }
        else
        {
            result[k] = v;
        }
    }

    return result;
}