UNPKG

twee

Version:

Twee Framework - the most powerful, elegant and extensive framework for Node.js based on Express.js

120 lines (97 loc) 3.07 kB
/* jQuery.extend extracted from the jQuery source & optimised for NodeJS Twitter: @FGRibreau / fgribreau.com Usage: var Extend = require('./Extend'); // Extend var obj = Extend({opt1:true, opt2:true}, {opt1:false}); // Deep Copy var clonedObject = Extend(true, {}, myObject); var clonedArray = Extend(true, [], ['a',['b','c',['d']]]); */ var toString = Object.prototype.toString, hasOwn = Object.prototype.hasOwnProperty, push = Array.prototype.push, slice = Array.prototype.slice, trim = String.prototype.trim, indexOf = Array.prototype.indexOf, // [[Class]] -> type pairs class2type = {}; // Populate the class2type map "Boolean Number String Function Array Date RegExp Object".split(" ").forEach(function(name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); }); function type(obj){ return obj == null ? String( obj ) : class2type[ toString.call(obj) ] || "object"; } function isPlainObject( obj ) { if ( !obj || type(obj) !== "object") { return false; } // Not own constructor property must be Object if ( obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } // Own properties are enumerated firstly, so to speed up, // if last one is own, then all properties are own. var key; for ( key in obj ) {} return key === undefined || hasOwn.call( obj, key ); } module.exports = function extend(){ var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && type(target) !== "function") { target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( isPlainObject(copy) || (copyIsArray = type(copy) === "array") ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && type(src) === "array" ? src : []; } else { clone = src && isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; };