方法1:将length
数组的属性设置为值0(零)。
这种简单的方式就像:
const arr = [ 1, 2, 3, 4, 5 ];
arr.length = 0;
后果
这种方式不会改变原始数组引用。这意味着,如果您将一个数组引用分配给具有赋值运算符(=)的其他数组,则在一个数组上应用此方法也将清除另一个数组。
记住,数组是非原始的。如果我们为变量赋值非原始值,那么该变量实际上不包含该值,而是保存引用。让我们通过一个例子更好地理解它:
const myArray = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info'
];
let yourArray = [ 'Some', 'thing' ];
yourArray = myArray;
console.time('Approach 1: .length = 0');
myArray.length = 0;
console.timeEnd('Approach 1: .length = 0');
console.group('Approach 1: Empty array using .length property of the Array')
console.log('myArray =>', myArray);
console.log('yourArray =>', yourArray);
console.groupEnd();
我在这里做的比预期多一点。我也在计算清空数组所用的时间(以毫秒为单位)。请注意,我将对所有方法做同样的事情,以便我们也了解性能。
回到输出:
Approach 1: .length = 0: 0.112ms
Approach 1: Empty array using .length property of the Array
myArray => []
yourArray => []
它说,
- 这种方法花了0.087ms。
- 正如我们看到的,
myArray
和yourArray
现在清空。
学习
在上面演示的情况下,如果您对同一个数组有两个引用,并且您使用了一个数组arr.length = 0
,则两个引用现在将指向相同的空数组。
因此学习是,如果你不希望其他数组在这种情况下也是一个空数组,请不要使用这种技术!
方法2:分配对新数组的引用
这很简单:
let arr = [ 1, 2, 3, 4, 5 ];
arr = [];
后果
此方法会改变原始数组引用。它将对空数组的引用分配给原始变量。让我们通过一个例子来理解这一点:
let hisArray = [ 'Some', 'thing' ];
let herArray = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info'
];
herArray = hisArray;
console.time('Approach 2: new assignment');
hisArray = [];
console.timeEnd('Approach 2: new assignment');
console.group('Approach 2: Empty array by assigning a new empty Array []')
console.log('hisArray =>', hisArray);
console.log('herArray =>', herArray);
console.groupEnd();
输出结果如下:
Approach 2: new assignment: 0.005ms
Approach 2: Empty array by assigning a new empty Array []
hisArray => []
herArray => [ 'Some', 'thing' ]
如你所见,
- 这种方法花费的时间比前一次少,即只需0.005 ms
- 原始数组
hisArray
已更改,但阵列的其他值herArray
仍未更改。
学习
仅当您没有对原始数组的其他引用时,此方法才适用。你应该小心这种方法,因为如果你从另一个变量引用这个数组,原始数组将保持不变。这可能会导致内存泄漏。
因此,学习是,如果您只通过其原始变量引用数组,请使用此方法。
方法3:使用pop()直到结束
另一种方法可以使用Array的pop()方法来删除元素。那么当想要删除所有元素时该怎么办?是! pop()
在循环中使用:
let someArray = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info'
];
console.time('Approach 3: pop()');
while(someArray.length > 0) {
someArray.pop();
}
console.timeEnd('Approach 3: pop()');
console.group('Approach 3: Use pop until death');
console.log('someArray => ', someArray);
console.groupEnd();
......输出是:
Approach 3: pop(): 0.012ms
Approach 3: Use pop until death
someArray => []
后果
随着数组中元素数量的增加,这种方法可能会变得很慢。您将发现此方法与之前方法之间存在真正的性能差异,其中Array中的元素数量较多。
学习
如果在处理大型数组时有办法使用以前的方法,请不要使用此方法。
方法4:使用拼接!
您可以使用splice
数组上的方法清空数组,它与方法1和方法2一样方便。但是,它带有隐藏成本!
let names = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info'
];
console.time('Approach 4: splice()');
let spliced = names.splice(0, names.length);
console.timeEnd('Approach 4: splice()');
console.group('Approach 4: Use splice!');
console.log('names => ', names);
console.log('spliced => ', spliced )
console.groupEnd();
仔细查看输出:
Approach 4: splice(): 0.005ms
Approach 4: Use splice!
names => []
spliced => [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info'
]
后果
使用.splice()
效果很好,性能也很好!但由于该.splice()
函数将返回包含所有已删除项的数组,因此它实际上将返回原始数组的副本。
学习
如果您不必承担原始数组的返回副本的开销,请不要使用此方法。可能有需要它的用例,但我很想听到这些!
方法5:Shift()怎么样?
这是我们的最后一种方法,使用shift()
方法。怎么shift()
办?
shift()方法从数组中删除第一个元素并返回已删除的元素。
看看下面的代码:
let againNames = [ 'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info', ' ',
'blog', 'dot', 'green', 'roots', 'dot', 'info'
];
console.time('Approach 5: shift()');
while (againNames.length > 0) {
againNames.shift();
}
console.timeEnd('Approach 5: shift()');
console.group('Approach 5: How about Shift()?');
console.log('againNames', againNames);
console.groupEnd();
......和输出:
Approach 5: shift(): 0.027ms
Approach 5: How about Shift()?
againNames []
后果/学习
当上面描述了其他更好的方法时,使用它会更慢并且没有多大意义。
结论
在我的日常代码审查中,我已经看到方法#1和2的使用大量用于清空阵列,
- 用法
.length()
- 分配
new Array
请注意,从阵列中删除一个/少数(或特定)元素并完全清空它(全部删除)的用例是不同的。因此,需要对它们进行不同的思考。
这些方法中的每一种都有其自身的后果(优点和缺点)和使用范围/时间。另一点需要注意的是,在确定实施方法时,性能也是关键。