Ensured that arrays are not considered same as plain object on deep extending. Fixes...
[jquery.git] / src / core.js
index 227dc30..23d40bd 100644 (file)
@@ -306,7 +306,7 @@ jQuery.fn.init.prototype = jQuery.fn;
 
 jQuery.extend = jQuery.fn.extend = function() {
        // copy reference to target object
-       var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
+       var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy, copyIsArray;
 
        // Handle a deep copy situation
        if ( typeof target === "boolean" ) {
@@ -340,10 +340,15 @@ jQuery.extend = jQuery.fn.extend = function() {
                                        continue;
                                }
 
-                               // Recurse if we're merging object literal values or arrays
-                               if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
-                                       var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
-                                               : jQuery.isArray(copy) ? [] : {};
+                               // 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 );
@@ -474,6 +479,11 @@ jQuery.extend({
                return jQuery.type(obj) === "array";
        },
 
+       // A crude way of determining if an object is a window
+       isWindow: function( obj ) {
+               return obj && typeof obj === "object" && "setInterval" in obj;
+       },
+
        type: function( obj ) {
                return obj == null ?
                        String( obj ) :
@@ -484,7 +494,7 @@ jQuery.extend({
                // Must be an Object.
                // Because of IE, we also have to check the presence of the constructor property.
                // Make sure that DOM nodes and window objects don't pass through, as well
-               if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || obj.setInterval ) {
+               if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
                        return false;
                }
                
@@ -632,7 +642,7 @@ jQuery.extend({
                        // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
                        var type = jQuery.type(array);
 
-                       if ( array.length == null || type === "string" || type === "function" || type === "regexp" || "setInterval" in array ) {
+                       if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
                                push.call( ret, array );
                        } else {
                                jQuery.merge( ret, array );