123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- 'use strict';
- /*!
- * node.extend
- * Copyright 2011, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * @fileoverview
- * Port of jQuery.extend that actually works on node.js
- */
- var is = require('is');
- var has = require('has');
- var defineProperty = Object.defineProperty;
- var gOPD = Object.getOwnPropertyDescriptor;
- // If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target
- var setProperty = function setP(target, name, value) {
- if (defineProperty && name === '__proto__') {
- defineProperty(target, name, {
- enumerable: true,
- configurable: true,
- value: value,
- writable: true
- });
- } else {
- target[name] = value;
- }
- };
- // Return undefined instead of __proto__ if '__proto__' is not an own property
- var getProperty = function getP(obj, name) {
- if (name === '__proto__') {
- if (!has(obj, name)) {
- return void 0;
- } else if (gOPD) {
- // In early versions of node, obj['__proto__'] is buggy when obj has
- // __proto__ as an own property. Object.getOwnPropertyDescriptor() works.
- return gOPD(obj, name).value;
- }
- }
- return obj[name];
- };
- module.exports = function extend() {
- var target = arguments[0] || {};
- var i = 1;
- var length = arguments.length;
- var deep = false;
- var options, name, src, copy, copyIsArray, clone;
- // 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' && !is.fn(target)) {
- target = {};
- }
- for (; i < length; i++) {
- // Only deal with non-null/undefined values
- options = arguments[i];
- if (options != null) {
- if (typeof options === 'string') {
- options = options.split('');
- }
- // Extend the base object
- for (name in options) {
- src = getProperty(target, name);
- copy = getProperty(options, name);
- // Prevent never-ending loop
- if (target === copy) {
- continue;
- }
- // Recurse if we're merging plain objects or arrays
- if (deep && copy && (is.hash(copy) || (copyIsArray = is.array(copy)))) {
- if (copyIsArray) {
- copyIsArray = false;
- clone = src && is.array(src) ? src : [];
- } else {
- clone = src && is.hash(src) ? src : {};
- }
- // Never move original objects, clone them
- setProperty(target, name, extend(deep, clone, copy));
- // Don't bring in undefined values
- } else if (typeof copy !== 'undefined') {
- setProperty(target, name, copy);
- }
- }
- }
- }
- // Return the modified object
- return target;
- };
|