Skip to content

Commit

Permalink
$.extend: added support for extending deeply
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiospampinato committed Sep 12, 2020
1 parent 22081a8 commit 6d3e671
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 9 deletions.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -890,10 +890,11 @@ $.each ( object, callback ) // => object

#### $.extend ()

Extends target object with properties from the source object.
Extends target object with properties from the source object, potentially deeply too.

```js
$.extend ( target, source ) // => object
$.extend ( true, target, source ) // => object
```

#### $.isArray ()
Expand Down
32 changes: 24 additions & 8 deletions src/core/extend.ts
@@ -1,29 +1,45 @@

// @require ./cash.ts
// @require ./type_checking.ts

interface CashStatic {
extend (): any;
extend ( deep: true, target: any, ...sources: any[] ): any;
extend ( target: any ): typeof cash;
extend ( target: any, ...objs: any[] ): any;
extend ( target: any, ...sources: any[] ): any;
}

interface Cash {
extend ( plugins: Record<any, any> ): this;
}

function extend ( target?: any, ...objs: any[] ) {
function extend ( ...sources: any[] ) {

const length = arguments.length;
const deep = isBoolean ( sources[0] ) ? sources.shift () : false,
target = sources.shift (),
length = sources.length;

if ( !length ) return {};
if ( !target ) return {};

if ( length === 1 ) return extend ( cash, target );
if ( !length ) return extend ( deep, cash, target );

for ( let i = 1; i < length; i++ ) {
for ( let i = 0; i < length; i++ ) {

for ( const key in arguments[i] ) {
const source = sources[i];

target[key] = arguments[i][key];
for ( const key in source ) {

if ( deep && ( isArray ( source[key] ) || isPlainObject ( source[key] ) ) ) {

if ( !target[key] || target[key].constructor !== source[key].constructor ) target[key] = new source[key].constructor ();

extend ( deep, target[key], source[key] );

} else {

target[key] = source[key];

}

}

Expand Down
6 changes: 6 additions & 0 deletions src/core/type_checking.ts
Expand Up @@ -34,6 +34,12 @@ function isElement ( x: any ): x is HTMLElement {

}

function isBoolean ( x: any ): x is boolean {

return typeof x === 'boolean';

}

function isFunction ( x: any ): x is Function {

return typeof x === 'function';
Expand Down
19 changes: 19 additions & 0 deletions test/modules/utilities.js
Expand Up @@ -73,6 +73,25 @@ describe ( 'Utilities', function () {

});

it ( 'can extend deeply', function ( t ) {

var result1 = $.extend ( true, { foo: 1 }, { bar: { inner: 2 } } );
t.deepEqual ( result1, { foo: 1, bar: { inner: 2 } } );

var result2 = $.extend ( true, { foo: 1 }, { bar: [1, 2] } );
t.deepEqual ( result2, { foo: 1, bar: [1, 2] } );

var result3 = $.extend ( true, {}, { foo: 1 }, { bar: { inner: 2, baz: { inner2: 3 } } } );
t.deepEqual ( result3, { foo: 1, bar: { inner: 2, baz: { inner2: 3 } } } );

var result4 = $.extend ( true, {}, { foo: 1, bar: { baz: 3 } }, { bar: { baz: 4 } } );
t.deepEqual ( result4, { foo: 1, bar: { baz: 4 } } );

var result5 = $.extend ( true, {}, { foo: 1, bar: { baz: 3 } }, { bar: { baz: 4 } }, { bar: { qux: 5 }} );
t.deepEqual ( result5, { foo: 1, bar: { baz: 4, qux: 5 } } );

});

it ( 'works also with either zero or one object(s)', function ( t ) {

t.deepEqual ( $.extend (), {} );
Expand Down

0 comments on commit 6d3e671

Please sign in to comment.