Skip to content

Commit 65f7a91

Browse files
deepAssign keeps prototypal chain of copied properties now (closes #110)
1 parent 81f8b7e commit 65f7a91

File tree

2 files changed

+19
-14
lines changed

2 files changed

+19
-14
lines changed

lib/utils/object.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,38 @@ export function deepAssign(target: any, ...sources: any[]): any {
2020
return target;
2121

2222
function assign(key: string | number, _target: any, _source: any): void {
23-
2423
const sourceValue = _source[key];
25-
if (sourceValue !== void 0) {
2624

25+
if (sourceValue !== void 0) {
2726
let targetValue = _target[key];
2827

2928
if (Array.isArray(sourceValue)) {
30-
3129
if (!Array.isArray(targetValue)) {
3230
targetValue = [];
3331
}
34-
3532
const length = targetValue.length;
3633

3734
sourceValue.forEach((_, index) => assign(length + index, targetValue, sourceValue));
38-
3935
} else if (typeof sourceValue === 'object') {
40-
41-
targetValue = targetValue || {};
42-
4336
if (sourceValue instanceof RegExp) {
44-
4537
targetValue = cloneRegExp(sourceValue);
4638
} else if (sourceValue instanceof Date) {
47-
4839
targetValue = new Date(sourceValue);
4940
} else if (sourceValue === null) {
50-
5141
targetValue = null;
5242
} else {
43+
if (!targetValue) {
44+
if (sourceValue.constructor && sourceValue.constructor.prototype) {
45+
targetValue = Object.create(sourceValue.constructor.prototype);
46+
} else {
47+
targetValue = {};
48+
}
49+
}
5350
deepAssign(targetValue, sourceValue);
5451
}
5552
} else {
56-
5753
targetValue = sourceValue;
5854
}
59-
6055
_target[key] = targetValue;
6156
}
6257
}
@@ -100,7 +95,7 @@ export function getAllPropertyNames(obj: any): string[] {
10095
obj = Object.getPrototypeOf(obj);
10196
} while (obj !== Object.prototype);
10297

103-
const exists: {[name: string]: boolean|undefined} = {};
98+
const exists: { [name: string]: boolean | undefined } = {};
10499

105100
return names.filter(name => {
106101

test/specs/utils/object.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ describe('utils', () => {
108108

109109
});
110110

111+
it('should keep prototype chain', () => {
112+
class Test {
113+
protoFn(): any {}
114+
}
115+
const copy = deepAssign({}, {test: new Test()});
116+
117+
expect(copy.test)
118+
.to.have.property('protoFn')
119+
.that.is.a('function');
120+
});
111121

112122
});
113123

0 commit comments

Comments
 (0)