Port of jQuery.extend for node.js and the browser providing object merging and deep cloning functionality
npx @tessl/cli install tessl/npm-extend@2.0.0extend is a port of jQuery's classic extend() method for Node.js and the browser. It provides reliable object merging and cloning functionality with support for both shallow and deep copying, making it ideal for configuration management, object composition, and data transformation tasks.
npm install extendconst extend = require('extend');For ES modules (via bundlers):
import extend from 'extend';const extend = require('extend');
// Shallow merging
const target = { a: 1, b: 2 };
const source = { b: 3, c: 4 };
const result = extend(target, source);
// result: { a: 1, b: 3, c: 4 }
// Note: target is modified and returned
// Deep merging
const deepTarget = {
config: { debug: false, port: 3000 },
features: { auth: true }
};
const deepSource = {
config: { debug: true, host: 'localhost' },
features: { logging: true }
};
const deepResult = extend(true, deepTarget, deepSource);
// Result: {
// config: { debug: true, port: 3000, host: 'localhost' },
// features: { auth: true, logging: true }
// }The extend function merges properties from one or more source objects into a target object, with optional deep cloning support.
/**
* Merge properties from source objects into target object
* @param {boolean} [deep] - If true, performs deep/recursive merge
* @param {object} target - The object to extend (will be modified)
* @param {object} object1 - Object containing properties to merge
* @param {...object} [objectN] - Additional objects to merge
* @returns {object} The modified target object
*/
function extend([deep], target, object1, ...objectN);Key Behaviors:
true as first argument for deep/recursive merging__proto__ property to prevent prototype pollutionUsage Examples:
// Multiple object merging
const config = extend(
{ server: { port: 3000 } },
{ server: { host: 'localhost' } },
{ database: { url: 'mongodb://localhost' } }
);
// Result: {
// server: { host: 'localhost' }, // shallow merge overwrites
// database: { url: 'mongodb://localhost' }
// }
// Deep merging preserves nested properties
const deepConfig = extend(true,
{ server: { port: 3000, ssl: false } },
{ server: { host: 'localhost' } }
);
// Result: {
// server: { port: 3000, ssl: false, host: 'localhost' }
// }
// Array merging (shallow)
const arrayResult = extend([1, 2, 3], [4, 5]);
// Result: [4, 5, 3] (array elements are overwritten by index)
// Deep array merging
const deepArrayResult = extend(true, [1, [2, 3]], [4, [5]]);
// Result: [4, [5, 3]] (nested arrays are merged)
// Cloning objects (target as empty object)
const original = { a: 1, nested: { b: 2 } };
const shallowClone = extend({}, original); // shallow clone
const deepClone = extend(true, {}, original); // deep clone
// Handle edge cases
extend(null, { a: 1 }); // Returns { a: 1 }
extend(undefined, { a: 1 }); // Returns { a: 1 }
extend({ a: 1 }); // Returns { a: 1 } (single argument)
extend(); // Returns {} (no arguments)Type Conversion Examples:
// String to object conversion
extend('hello', { 0: 'H' }); // Result: { 0: 'H', 1: 'e', 2: 'l', 3: 'l', 4: 'o' }
// Number becomes empty object
extend(42, { a: 1 }); // Result: { a: 1 }
// Function becomes empty object (then gets properties)
extend(function() {}, { a: 1 }); // Result: { a: 1 }
// Date object behavior
extend(new Date(), { custom: 'prop' }); // Adds custom property to date
// Special property handling (constructor, isPrototypeOf)
extend({}, { constructor: 'fake', isPrototypeOf: 'not a function' });
// Result: { constructor: 'fake', isPrototypeOf: 'not a function' }Security Considerations:
// Safe __proto__ handling
const malicious = { __proto__: { evil: true } };
const target = {};
extend(target, malicious);
// target.__proto__ is set as own property, doesn't affect prototype chain