From c10f87120f6fb2c6c269e766d6988e9be946dd03 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Thu, 16 Jul 2009 07:32:03 +0000 Subject: [PATCH] jQuery.extend(true, Object, Object) copies custom objects correctly. - Also update jQuery.isObject to handle this case correctly --- src/core.js | 16 +++++++++++++--- test/unit/core.js | 14 ++++++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/core.js b/src/core.js index 6f8d40f..b51886f 100644 --- a/src/core.js +++ b/src/core.js @@ -243,9 +243,15 @@ jQuery.extend = jQuery.fn.extend = function() { // Recurse if we're merging object values if ( deep && copy && typeof copy === "object" && !copy.nodeType ) { - target[ name ] = jQuery.extend( deep, - // Never move original objects, clone them - src || ( jQuery.isArray(copy) ? [ ] : { } ), copy ); + var clone; + + if( src ) clone = src; + else if( jQuery.isArray(copy) ) clone = [ ]; + else if( jQuery.isObject(copy) ) clone = { }; + else clone = copy; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { @@ -281,6 +287,10 @@ jQuery.extend({ return toString.call(obj) === "[object Array]"; }, + isObject: function( obj ) { + return this.constructor.call(obj) === Object; + }, + // check if an element is in a (or is an) XML document isXMLDoc: function( elem ) { return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || diff --git a/test/unit/core.js b/test/unit/core.js index fe2e992..0f6d5b3 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -435,7 +435,7 @@ test("jQuery.merge()", function() { }); test("jQuery.extend(Object, Object)", function() { - expect(21); + expect(23); var settings = { xnumber1: 5, xnumber2: 7, xstring1: "peter", xstring2: "pan" }, options = { xnumber2: 1, xstring2: "x", xxx: "newstring" }, @@ -463,9 +463,19 @@ test("jQuery.extend(Object, Object)", function() { var empty = {}; var optionsWithLength = { foo: { length: -1 } }; jQuery.extend(true, empty, optionsWithLength); - isObj( empty.foo, optionsWithLength.foo, "The length property must copy correctly" ); + empty = {}; + var optionsWithDate = { foo: { date: new Date } }; + jQuery.extend(true, empty, optionsWithDate); + isObj( empty.foo, optionsWithDate.foo, "Dates copy correctly" ); + + var myKlass = function() {}; + empty = {}; + var optionsWithCustomObject = { foo: { date: new myKlass } }; + jQuery.extend(true, empty, optionsWithCustomObject); + isObj( empty.foo, optionsWithCustomObject.foo, "Custom objects copy correctly" ); + var nullUndef; nullUndef = jQuery.extend({}, options, { xnumber2: null }); ok( nullUndef.xnumber2 === null, "Check to make sure null values are copied"); -- 1.7.10.4