[英]jQuery.extend throws stack overflow exception with self references
I was working on a JavaScript application when I noticed that: using jQuery.extend function has a special behaviour when used with object that have a reference to them self. 我注意到一个JavaScript应用程序时:使用jQuery.extend函数与具有自身引用的对象一起使用时,具有特殊的行为。
If you run this script: 如果运行此脚本:
var x = new (function(){ this.self = this });
var y = {}; y.self = y;
console.log($.extend(true, {}, x))
console.log($.extend(true, {}, y))
You will notice that the extending with 'x' works fine, while extending with 'y' throws a stack overflow exception. 您会注意到,用'x'扩展可以正常工作,而用'y'扩展可以引发堆栈溢出异常。
Can you explain this behaviour? 您能解释一下这种行为吗?
The difference is whether the object is a plain object or not. 区别在于对象是否为普通对象。 x
had a constructor; x
有一个构造函数; so when extend
comes to the value of self
, I suppose jQuery doesn't want to deep copy it, since it doesn't know that it can recreate it properly, and ends up with just a plain, non-deep copy for that attribute. 因此,当extend
涉及self
的值时,我想jQuery不想对其进行深度复制,因为它不知道它可以正确地重新创建它,并且最终仅对该属性进行了普通的非深度复制。
y
, on the other hand, checks out as a POJO, and extend
thinks it's okay to deep-copy it, which results in the infinite recursion. 另一方面, y
作为POJO签出,并且extend
认为可以对其进行深复制,从而导致无限递归。
Look at extend
code , where it says " // Recurse if we're merging plain objects or arrays
" 看一下extend
代码 ,它上面写着“ // Recurse if we're merging plain objects or arrays
,则// Recurse if we're merging plain objects or arrays
”
jQuery's .extend()
does a deep copy of plain objects and arrays, but not a deep copy of function objects. jQuery的.extend()
可以对普通对象和数组进行深层复制,而不能对函数对象进行深层复制。
Since x
is a function object, it doesn't do a deep copy of that. 由于x
是函数对象,因此不会对其进行深层复制。
But since y
is a plain object, it does try to do a deep copy and runs into the infinite loop. 但是由于y
是一个普通对象,因此它确实尝试进行深层复制并遇到无限循环。
From the jQuery .extend()
source: 从jQuery .extend()
源:
// Recurse if we're merging plain objects or arrays
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src : [];
} else {
clone = src && jQuery.isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
You can see that it is checking to see if the property is a plain object or an array. 您可以看到它正在检查该属性是纯对象还是数组。 A function object will not be either. 功能对象也不是。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.