whet.extend.coffee
1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
###
* whet.extend v0.9.7
* Standalone port of jQuery.extend that actually works on node.js
* https://github.com/Meettya/whet.extend
*
* Copyright 2012, Dmitrii Karpich
* Released under the MIT License
###
module.exports = extend = (deep, target, args...) ->
unless _isClass deep, 'Boolean'
args.unshift target
[ target, deep ] = [ deep or {}, false ]
#Handle case when target is a string or something (possible in deep copy)
target = {} if _isPrimitiveType target
for options in args when options?
for name, copy of options
target[name] = _findValue deep, copy, target[name]
target
###
Internal methods from now
###
_isClass = (obj, str) ->
"[object #{str}]" is Object::toString.call obj
_isOwnProp = (obj, prop) ->
Object::hasOwnProperty.call obj, prop
_isTypeOf = (obj, str) ->
str is typeof obj
_isPlainObj = (obj) ->
return false unless obj
return false if obj.nodeType or obj.setInterval or not _isClass obj, 'Object'
# Not own constructor property must be Object
return false if obj.constructor and
not _isOwnProp(obj, 'constructor') and
not _isOwnProp(obj.constructor::, 'isPrototypeOf')
# Own properties are enumerated firstly, so to speed up,
# if last one is own, then all properties are own.
key for key of obj
key is undefined or _isOwnProp obj, key
_isPrimitiveType = (obj) ->
not ( _isTypeOf(obj, 'object') or _isTypeOf(obj, 'function') )
_prepareClone = (copy, src) ->
if _isClass copy, 'Array'
if _isClass src, 'Array' then src else []
else
if _isPlainObj src then src else {}
_findValue = (deep, copy, src) ->
# if we're merging plain objects or arrays
if deep and ( _isClass(copy, 'Array') or _isPlainObj copy )
clone = _prepareClone copy, src
extend deep, clone, copy
else
copy