Skip to content

Commit c929567

Browse files
committed
Prevent object reference sharing in array operations
Shallow copy objects in `pull`, `push`, `insert`, and `update` functions to avoid unintended reference sharing. Added corresponding test cases to ensure objects are not shared between input and output arrays.
1 parent 9984666 commit c929567

2 files changed

Lines changed: 31 additions & 11 deletions

File tree

src/array/array.spec.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ describe('array', () => {
3535
it('should return not modify source', () => {
3636
expect(sourceArray).toEqual([1, 2]);
3737
});
38+
39+
it('should not share object reference', () => {
40+
const obj = {id: 1};
41+
const result = pull([{id: 2}], obj);
42+
expect(result[0]).not.toBe(obj);
43+
});
3844
});
3945

4046
describe('push', () => {
@@ -47,6 +53,11 @@ describe('array', () => {
4753
it('should return not modify source', () => {
4854
expect(sourceArray).toEqual([1, 2]);
4955
});
56+
it('should not share object reference', () => {
57+
const obj = {id: 1};
58+
const result = push([{id: 2}], obj);
59+
expect(result[2]).not.toBe(obj);
60+
});
5061
});
5162

5263
describe('move', () => {
@@ -76,8 +87,11 @@ describe('array', () => {
7687
const result = insert(null, 1, 'A');
7788
expect(result).toStrictEqual(['A']);
7889
});
79-
80-
90+
it('should not share object reference', () => {
91+
const obj = {id: 9};
92+
const result = insert([{id: 1}, {id: 2}], 1, obj);
93+
expect(result[1]).not.toBe(obj);
94+
});
8195
});
8296

8397

src/array/array.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import {SortOrder, TArrayOrEmpty, TEmpty,TGroupByFn, TGroupTreeBy, TSortByFn} fr
1010
* @param pullData
1111
*/
1212
export function pull<T, A extends TArrayOrEmpty<T>>(arrayData: A, pullData: T): A {
13-
if(!arrayData) return [pullData] as A;
14-
return [pullData].concat(arrayData.slice(0)) as A;
13+
// 防止物件共享引用:對物件進行淺拷貝
14+
const item = (pullData && typeof pullData === 'object') ? {...pullData} : pullData;
15+
if(!arrayData) return [item] as A;
16+
return [item].concat(arrayData.slice(0)) as A;
1517
}
1618

1719
/**
@@ -24,8 +26,10 @@ export function pull<T, A extends TArrayOrEmpty<T>>(arrayData: A, pullData: T):
2426
* @param pushData
2527
*/
2628
export function push<T, A extends TArrayOrEmpty<T>>(arrayData: A, pushData: T): T[] {
27-
if(!arrayData) return [pushData] as T[];
28-
return arrayData.slice(0).concat(pushData) as T[];
29+
// 防止物件共享引用:對物件進行淺拷貝
30+
const item = (pushData && typeof pushData === 'object') ? {...pushData} : pushData;
31+
if(!arrayData) return [item] as T[];
32+
return arrayData.slice(0).concat(item) as T[];
2933
}
3034

3135
/**
@@ -39,8 +43,10 @@ export function push<T, A extends TArrayOrEmpty<T>>(arrayData: A, pushData: T):
3943
* @param data
4044
*/
4145
export function insert<T, A extends TArrayOrEmpty<T>>(arrayData: A, index: number, data: T): T[] {
42-
if(!arrayData) return [data] as T[];
43-
return [...arrayData.slice(0, index), data, ...arrayData.slice(index)] as T[];
46+
// 防止物件共享引用:對物件進行淺拷貝
47+
const item = (data && typeof data === 'object') ? {...data} : data;
48+
if(!arrayData) return [item] as T[];
49+
return [...arrayData.slice(0, index), item, ...arrayData.slice(index)] as T[];
4450
}
4551

4652
/**
@@ -150,13 +156,13 @@ export function updateByIndex<T, A extends TArrayOrEmpty<T>>(arrayData: T[]|A, i
150156
if(index === -1 || !arrayData || index > arrayData.length - 1) return arrayData as A;
151157

152158
// Copy new object
153-
const newDaa: T = {...arrayData[index]};
159+
const newData: T = {...arrayData[index]};
154160

155-
updateFn(newDaa);
161+
updateFn(newData);
156162

157163
// Copy new array
158164
const newArrayData: T[] = [...arrayData];
159-
newArrayData[index] = newDaa;
165+
newArrayData[index] = newData;
160166
return newArrayData as A;
161167
}
162168

0 commit comments

Comments
 (0)