Skip to content

Instantly share code, notes, and snippets.

@derekchiang
Created May 24, 2013 07:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derekchiang/5641929 to your computer and use it in GitHub Desktop.
Save derekchiang/5641929 to your computer and use it in GitHub Desktop.
A standalone copy of jQuery's extend(), in CoffeeScript
# Adopted from: https://github.com/dansdom/extend
# Translated using js2coffee
extend = ->
options = undefined
name = undefined
src = undefined
copy = undefined
copyIsArray = undefined
clone = undefined
target = arguments[0] or {}
i = 1
length = arguments.length
deep = false
objectHelper =
# helper which replicates the jquery internal functions
hasOwn: Object::hasOwnProperty
class2type: {}
type: (obj) ->
(if not obj? then String(obj) else objectHelper.class2type[Object::toString.call(obj)] or "object")
isPlainObject: (obj) ->
return false if not obj or objectHelper.type(obj) isnt "object" or obj.nodeType or objectHelper.isWindow(obj)
try
return false if obj.constructor and not objectHelper.hasOwn.call(obj, "constructor") and not objectHelper.hasOwn.call(obj.constructor::, "isPrototypeOf")
catch e
return false
key = undefined
for key of obj
{}
key is `undefined` or objectHelper.hasOwn.call(obj, key)
isArray: Array.isArray or (obj) ->
objectHelper.type(obj) is "array"
isFunction: (obj) ->
objectHelper.type(obj) is "function"
isWindow: (obj) ->
obj? and obj is obj.window
# end of objectHelper
# Handle a deep copy situation
if typeof target is "boolean"
deep = target
target = arguments[1] or {}
# skip the boolean and the target
i = 2
# Handle case when target is a string or something (possible in deep copy)
target = {} if typeof target isnt "object" and not objectHelper.isFunction(target)
# If no second argument is used then this can extend an object that is using this method
if length is i
target = this
--i
while i < length
# Only deal with non-null/undefined values
if (options = arguments[i])?
# extend the base object
for name of options
src = target[name]
copy = options[name]
# Prevent never-ending loop
continue if target is copy
# Recurse if we're merging plain objects or arrays
if deep and copy and (objectHelper.isPlainObject(copy) or (copyIsArray = objectHelper.isArray(copy)))
if copyIsArray
copyIsArray = false
clone = (if src and objectHelper.isArray(src) then src else [])
else
clone = (if src and objectHelper.isPlainObject(src) then src else {})
# Never move original objects, clone them
target[name] = extend(deep, clone, copy)
# Don't bring in undefined values
else target[name] = copy if copy isnt `undefined`
i++
# Return the modified object
target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment