Skip to content

Commit 298bd0f

Browse files
committed
Improve(Extend): Support Symbol
1 parent 535ee4e commit 298bd0f

File tree

2 files changed

+46
-50
lines changed

2 files changed

+46
-50
lines changed

packages/extend/src/index.ts

Lines changed: 23 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
function isSpecificValue(val) {
1+
function isSpecificValue(val: any): boolean {
22
const _Buffer = typeof Buffer !== 'undefined' ? Buffer : null
33
return (
4-
_Buffer && val instanceof _Buffer
5-
|| val instanceof Date
6-
|| val instanceof RegExp
7-
) ? true : false
4+
(_Buffer && val instanceof _Buffer) ||
5+
val instanceof Date ||
6+
val instanceof RegExp
7+
)
88
}
99

10-
function cloneSpecificValue(val) {
10+
function cloneSpecificValue(val: any): any {
1111
const _Buffer = typeof Buffer !== 'undefined' ? Buffer : null
1212
if (_Buffer && val instanceof Buffer) {
1313
const x = Buffer.alloc(val.length)
@@ -22,10 +22,7 @@ function cloneSpecificValue(val) {
2222
}
2323
}
2424

25-
/**
26-
* Recursive cloning array.
27-
*/
28-
function deepCloneArray(arr: any[]) {
25+
function deepCloneArray(arr: any[]): any[] {
2926
const clone = []
3027
arr.forEach(function (item, index) {
3128
if (typeof item === 'object' && item !== null) {
@@ -43,68 +40,44 @@ function deepCloneArray(arr: any[]) {
4340
return clone
4441
}
4542

46-
function safeGetProperty(object, property) {
47-
return property === '__proto__' ? undefined : object[property]
43+
function safeGetProperty(object: any, property: string | symbol): any {
44+
if (property === '__proto__') return undefined
45+
return Object.prototype.hasOwnProperty.call(object, property)
46+
? object[property]
47+
: undefined
4848
}
4949

50-
/**
51-
* Extening object that entered in first argument.
52-
*
53-
* Returns extended object or false if have no target object or incorrect type.
54-
*
55-
* If you wish to clone source object (without modify it), just use empty new
56-
* object as first argument, like this:
57-
* extend({}, yourObj_1, [yourObj_N]);
58-
*/
59-
export default function extend(...sources: any[]) {
60-
const target = {}
61-
62-
let val: any, src: any
50+
export default function extend(...sources: any[]): any {
51+
const target: any = {}
6352

6453
sources.forEach(function (obj) {
65-
// skip argument if isn't an object, is null, or is an array
6654
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
6755
return
6856
}
6957

70-
Object.keys(obj).forEach(function (key) {
71-
src = safeGetProperty(target, key) // source value
72-
val = safeGetProperty(obj, key) // new value
58+
Reflect.ownKeys(obj).forEach(function (key) {
59+
const src = safeGetProperty(target, key)
60+
const val = safeGetProperty(obj, key)
7361

74-
// recursion prevention
7562
if (val === target) {
7663
return
77-
78-
/**
79-
* if new value isn't object then just overwrite by new value
80-
* instead of extending.
81-
*/
8264
} else if (typeof val !== 'object' || val === null) {
8365
target[key] = val
84-
return
85-
86-
// just clone arrays (and recursive clone objects inside)
8766
} else if (Array.isArray(val)) {
8867
target[key] = deepCloneArray(val)
89-
return
90-
91-
// custom cloning and overwrite for specific objects
9268
} else if (isSpecificValue(val)) {
9369
target[key] = cloneSpecificValue(val)
94-
return
95-
96-
// overwrite by new value if source isn't object or array
97-
} else if (typeof src !== 'object' || src === null || Array.isArray(src)) {
70+
} else if (
71+
typeof src !== 'object' ||
72+
src === null ||
73+
Array.isArray(src)
74+
) {
9875
target[key] = extend({}, val)
99-
return
100-
101-
// source value and new value is objects both, extending...
10276
} else {
10377
target[key] = extend(src, val)
104-
return
10578
}
10679
})
10780
})
10881

10982
return target
110-
}
83+
}

packages/extend/tests/test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,4 +277,27 @@ it('prevent source contamination', () => {
277277
}
278278
}
279279
})
280+
})
281+
282+
test('symbol', ()=> {
283+
const C = Symbol('c')
284+
const D = Symbol('d')
285+
const obj1 = {
286+
a: 1,
287+
b: 2,
288+
[C]: 3
289+
}
290+
const obj2 = {
291+
b: 3,
292+
c: 4,
293+
[D]: 5
294+
}
295+
const result = extend(obj1, obj2)
296+
expect(result).toEqual({
297+
a: 1,
298+
b: 3,
299+
c: 4,
300+
[C]: 3,
301+
[D]: 5
302+
})
280303
})

0 commit comments

Comments
 (0)