今天在使用JS处理字符串数组寻找好用的方法时,发现了一位全能选手splice(),为什么说它是全能选手呢?因为它可以删除元素,也可以添加元素,而且还可以同时进行删除和添加元素的操作,666啊,接下来让我们了解一下这位神奇的朋友。
先看基本语法:
语法
array.splice(index,howmany,item1,.....,itemX)
参数
参数 | 描述 |
---|---|
index | 必需。规定从何处添加/删除元素。 该参数是开始插入和(或)删除的数组元素的下标,必须是数字。 |
howmany | 可选。规定应该删除多少元素。必须是数字,但可以是 "0"。 如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素。 |
item1, ..., itemX | 可选。要添加到数组的新元素 |
返回值
Type | 描述 |
---|---|
Array | 如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组。 |
技术细节
JavaScript 版本: | 1.2 |
---|
浏览器支持
基本上所有主要浏览器都支持splice()方法,比如IE、Firefox、欧朋、Chrome、Safari等。
实例
在本例中我们将删除位于 index=3 的元素,并添加一个新元素来替代被删除的元素:
var arr = new Array(6)
arr[0] = "Geo"
arr[1] = "John"
arr[2] = "Tome"
arr[3] = "James"
arr[4] = "Adrew"
arr[5] = "Marter"
document.write(arr + "<br />")
arr.splice(3,1,"William")
document.write(arr)
运行结果:
Geo,John,Tome,James,Adrew,Marter
Geo,John,Tome,William,Adrew,Marter
源码
方法splice()在底层的源码实现中,实际上对应着方法ArraySplice(),源码位于v8/src/js/array.js中。二者的对应关系是在InstallFunctions中绑定的,具体看代码:
// Set up non-enumerable functions of the Array.prototype object and
// set their names.
// Manipulate the length of some of the functions to meet
// expectations set by ECMA-262 or Mozilla.
// 方法名对应的绑定关系列表
utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
"toString", getFunction("toString", ArrayToString),
"toLocaleString", getFunction("toLocaleString", ArrayToLocaleString),
"join", getFunction("join", ArrayJoin),
"pop", getFunction("pop", ArrayPop),
"push", getFunction("push", ArrayPush, 1),
"reverse", getFunction("reverse", ArrayReverse),
"shift", getFunction("shift", ArrayShift),
"unshift", getFunction("unshift", ArrayUnshift, 1),
"slice", getFunction("slice", ArraySlice, 2),
"splice", getFunction("splice", ArraySplice, 2),
"sort", getFunction("sort", ArraySort),
"filter", getFunction("filter", ArrayFilter, 1),
"forEach", getFunction("forEach", ArrayForEach, 1),
"some", getFunction("some", ArraySome, 1),
"every", getFunction("every", ArrayEvery, 1),
"map", getFunction("map", ArrayMap, 1),
"indexOf", getFunction("indexOf", null, 1),
"lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1),
"reduce", getFunction("reduce", ArrayReduce, 1),
"reduceRight", getFunction("reduceRight", ArrayReduceRight, 1),
"copyWithin", getFunction("copyWithin", ArrayCopyWithin, 2),
"find", getFunction("find", ArrayFind, 1),
"findIndex", getFunction("findIndex", ArrayFindIndex, 1),
"fill", getFunction("fill", ArrayFill, 1),
"includes", getFunction("includes", null, 1)
]);
其中,ArraySplice()方法的具体实现如下:
function ArraySplice(start, delete_count) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice");
var num_arguments = arguments.length;
var array = TO_OBJECT(this);
var len = TO_LENGTH(array.length);
var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
start_i);
var deleted_elements = ArraySpeciesCreate(array, del_count);
deleted_elements.length = del_count;
var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
if (del_count != num_elements_to_add && %object_is_sealed(array)) {
throw %make_type_error(kArrayFunctionsOnSealed);
} else if (del_count > 0 && %object_is_frozen(array)) {
throw %make_type_error(kArrayFunctionsOnFrozen);
}
var changed_elements = del_count;
// 如果删除的元素个数和增加的元素个数不一致,则计算需要移动的元素位数
if (num_elements_to_add != del_count) {
// If the slice needs to do a actually move elements after the insertion
// point, then include those in the estimate of changed elements.
changed_elements += len - start_i - del_count;
}
if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
%NormalizeElements(array);
if (IS_ARRAY(deleted_elements)) %NormalizeElements(deleted_elements);
SparseSlice(array, start_i, del_count, len, deleted_elements);
SparseMove(array, start_i, del_count, len, num_elements_to_add);
} else {
SimpleSlice(array, start_i, del_count, len, deleted_elements);
SimpleMove(array, start_i, del_count, len, num_elements_to_add);
}
// 从删除元素的位置开始添加元素
var i = start_i;
var arguments_index = 2;
var arguments_length = arguments.length;
while (arguments_index < arguments_length) {
array[i++] = arguments[arguments_index++];
}
array.length = len - del_count + num_elements_to_add;
// 返回删除的元素
return deleted_elements;
}