Skip to content

Commit

Permalink
enable deep copy via $.extend(true, target, source)
Browse files Browse the repository at this point in the history
Closes #356
  • Loading branch information
mislav committed Sep 8, 2012
1 parent 3c980c6 commit b797806
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/zepto.js
Expand Up @@ -177,14 +177,24 @@ var Zepto = (function() {
return zepto.init(selector, context)
}

function extend(target, source, deep) {
for (key in source)
if (deep && isPlainObject(source[key])) {
if (!isPlainObject(target[key])) target[key] = {}
extend(target[key], source[key], deep)
}
else if (source[key] !== undefined) target[key] = source[key]
}

// Copy all but undefined properties from one or more
// objects to the `target` object.
$.extend = function(target){
slice.call(arguments, 1).forEach(function(source) {
for (key in source)
if (source[key] !== undefined)
target[key] = source[key]
})
var deep, args = slice.call(arguments, 1)
if (typeof target == 'boolean') {
deep = target
target = args.shift()
}
args.forEach(function(arg){ extend(target, arg, deep) })
return target
}

Expand Down
33 changes: 33 additions & 0 deletions test/zepto.html
Expand Up @@ -368,6 +368,39 @@ <h1>Zepto DOM unit tests</h1>

// undefined values are not copied over
t.assertSame({a:1}, $.extend({a:1}, {b:undefined}))

// shallow by default
obj = $.extend({ a:{b:"c"} }, { a:{d:"e"} })
t.assertSame({d:"e"}, obj.a)
},

testExtendDeep: function(t){
var obj = { a:{b:"c", x:{y:"z"}} }
$.extend(true, obj, { a:{d:"e"} }, { a:{b:"B", f:"g", x:{q:"x"}} })

t.assertEqual('a', Object.keys(obj).join(','))
t.assertEqual('b,d,f,x', Object.keys(obj.a).sort().join(','))
t.assertEqual('B', obj.a.b)
t.assertEqual('e', obj.a.d)
t.assertEqual('g', obj.a.f)
t.assertEqual('z', obj.a.x.y)
t.assertEqual('x', obj.a.x.q)

// creates non-existing keys on target object
obj = {}
$.extend(true, obj, { a:{b:"c"} })
t.assertEqual('a', Object.keys(obj).join(','))
t.assertEqual('c', obj.a.b)

// skips iterating over DOM elements
obj = {}
var dom = $('#some_element').get(0)
$.extend(true, obj, { element: dom })
t.assertIdentical(dom, obj.element)

// can override DOM element
$.extend(true, obj, { element:{a:'b'} })
t.assertEqual('b', obj.element.a)
},

testExtensionAPI: function(t) {
Expand Down

0 comments on commit b797806

Please sign in to comment.