JS之splice()方法刨根问底

举报
liuzhen007 发表于 2021/05/28 03:59:55 2021/05/28
【摘要】 目录 语法 参数 返回值 技术细节 浏览器支持  实例 源码 今天在使用JS处理字符串数组寻找好用的方法时,发现了一位全能选手splice(),为什么说它是全能选手呢?因为它可以删除元素,也可以添加元素,而且还可以同时进行删除和添加元素的操作,666啊,接下来让我们了解一下这位神奇的朋友。 先看基本语法: 语法 array.splice(in...

目录

语法

参数

返回值

技术细节

浏览器支持 

实例

源码


今天在使用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 的元素,并添加一个新元素来替代被删除的元素:


  
  1. var arr = new Array(6)
  2. arr[0] = "Geo"
  3. arr[1] = "John"
  4. arr[2] = "Tome"
  5. arr[3] = "James"
  6. arr[4] = "Adrew"
  7. arr[5] = "Marter"
  8. document.write(arr + "<br />")
  9. arr.splice(3,1,"William")
  10. document.write(arr)

运行结果: 


  
  1. Geo,John,Tome,James,Adrew,Marter
  2. Geo,John,Tome,William,Adrew,Marter

源码

方法splice()在底层的源码实现中,实际上对应着方法ArraySplice(),源码位于v8/src/js/array.js中。二者的对应关系是在InstallFunctions中绑定的,具体看代码:


  
  1. // Set up non-enumerable functions of the Array.prototype object and
  2. // set their names.
  3. // Manipulate the length of some of the functions to meet
  4. // expectations set by ECMA-262 or Mozilla.
  5. // 方法名对应的绑定关系列表
  6. utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
  7. "toString", getFunction("toString", ArrayToString),
  8. "toLocaleString", getFunction("toLocaleString", ArrayToLocaleString),
  9. "join", getFunction("join", ArrayJoin),
  10. "pop", getFunction("pop", ArrayPop),
  11. "push", getFunction("push", ArrayPush, 1),
  12. "reverse", getFunction("reverse", ArrayReverse),
  13. "shift", getFunction("shift", ArrayShift),
  14. "unshift", getFunction("unshift", ArrayUnshift, 1),
  15. "slice", getFunction("slice", ArraySlice, 2),
  16. "splice", getFunction("splice", ArraySplice, 2),
  17. "sort", getFunction("sort", ArraySort),
  18. "filter", getFunction("filter", ArrayFilter, 1),
  19. "forEach", getFunction("forEach", ArrayForEach, 1),
  20. "some", getFunction("some", ArraySome, 1),
  21. "every", getFunction("every", ArrayEvery, 1),
  22. "map", getFunction("map", ArrayMap, 1),
  23. "indexOf", getFunction("indexOf", null, 1),
  24. "lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1),
  25. "reduce", getFunction("reduce", ArrayReduce, 1),
  26. "reduceRight", getFunction("reduceRight", ArrayReduceRight, 1),
  27. "copyWithin", getFunction("copyWithin", ArrayCopyWithin, 2),
  28. "find", getFunction("find", ArrayFind, 1),
  29. "findIndex", getFunction("findIndex", ArrayFindIndex, 1),
  30. "fill", getFunction("fill", ArrayFill, 1),
  31. "includes", getFunction("includes", null, 1)
  32. ]);

其中,ArraySplice()方法的具体实现如下:


  
  1. function ArraySplice(start, delete_count) {
  2. CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice");
  3. var num_arguments = arguments.length;
  4. var array = TO_OBJECT(this);
  5. var len = TO_LENGTH(array.length);
  6. var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
  7. var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
  8. start_i);
  9. var deleted_elements = ArraySpeciesCreate(array, del_count);
  10. deleted_elements.length = del_count;
  11. var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
  12. if (del_count != num_elements_to_add && %object_is_sealed(array)) {
  13. throw %make_type_error(kArrayFunctionsOnSealed);
  14. } else if (del_count > 0 && %object_is_frozen(array)) {
  15. throw %make_type_error(kArrayFunctionsOnFrozen);
  16. }
  17. var changed_elements = del_count;
  18. // 如果删除的元素个数和增加的元素个数不一致,则计算需要移动的元素位数
  19. if (num_elements_to_add != del_count) {
  20. // If the slice needs to do a actually move elements after the insertion
  21. // point, then include those in the estimate of changed elements.
  22. changed_elements += len - start_i - del_count;
  23. }
  24. if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
  25. %NormalizeElements(array);
  26. if (IS_ARRAY(deleted_elements)) %NormalizeElements(deleted_elements);
  27. SparseSlice(array, start_i, del_count, len, deleted_elements);
  28. SparseMove(array, start_i, del_count, len, num_elements_to_add);
  29. } else {
  30. SimpleSlice(array, start_i, del_count, len, deleted_elements);
  31. SimpleMove(array, start_i, del_count, len, num_elements_to_add);
  32. }
  33. // 从删除元素的位置开始添加元素
  34. var i = start_i;
  35. var arguments_index = 2;
  36. var arguments_length = arguments.length;
  37. while (arguments_index < arguments_length) {
  38. array[i++] = arguments[arguments_index++];
  39. }
  40. array.length = len - del_count + num_elements_to_add;
  41. // 返回删除的元素
  42. return deleted_elements;
  43. }

参考链接

http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.12

https://github.com/v8/v8/blob/ad82a40509c5b5b4680d4299c8f08d6c6d31af3c/src/js/array.js

https://www.w3school.com.cn/jsref/jsref_splice.asp

 

文章来源: liuzhen.blog.csdn.net,作者:Data-Mining,版权归原作者所有,如需转载,请联系作者。

原文链接:liuzhen.blog.csdn.net/article/details/106769936

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。