JS中从Array.slice()与Array.splice()的底层实现原理分析区别
来源:互联网 发布:单片机如何烧程序 编辑:程序博客网 时间:2024/06/07 16:59
1.Array.prototype.slice()
slice() 方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对像,原始数组不会改变。
arrayObject.slice(start,end)
- start (可选,如果start不写则从0开始)从该索引处开始提取原数组中的元素。
如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组的倒数第二个元素到最后一个元素(包含最后一个元素)。 - end(可选)在该索引处结束提取原数组元素(从0开始)。slice会提取原数组中索引从 begin 到 end 的所有元素(包含begin,但不包含end)。
*1.如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1)表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。
2.如果 end 被省略,则slice 会一直提取到原数组末尾。
3.如果 end 大于数组长度,slice 也会一直提取到原数组末尾。*
原理:
(应该都能看懂)
// This will work for genuine arrays, array-like objects, // NamedNodeMap (attributes, entities, notations), // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes), // and will not fail on other DOM objects (as do DOM elements in IE < 9) Array.prototype.slice = function(begin, end) { // IE < 9 gets unhappy with an undefined end argument end = (typeof end !== 'undefined') ? end : this.length; // For native Array objects, we use the native slice function if (Object.prototype.toString.call(this) === '[object Array]'){ return _slice.call(this, begin, end); } // For array like object we handle it ourselves. var i, cloned = [], size, len = this.length; // Handle negative value for "begin" var start = begin || 0; start = (start >= 0) ? start : Math.max(0, len + start); // Handle negative value for "end" var upTo = (typeof end == 'number') ? Math.min(end, len) : len; if (end < 0) { upTo = len + end; } // Actual expected size of the slice size = upTo - start; if (size > 0) { cloned = new Array(size); if (this.charAt) { for (i = 0; i < size; i++) { cloned[i] = this.charAt(start + i); } } else { for (i = 0; i < size; i++) { cloned[i] = this[start + i]; } } } return cloned; };
还可以查看V8源码第587行:直达
2.Array.prototype.splice()
splice()方法通过删除现有元素和/或添加新元素来更改一个数组的内容。
原型:Array.prototype.splice (start, deleteCount, item1, item2, … )
- start
指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从1计数)。 - deleteCount (可选)
整数,表示要移除的数组元素的个数。如果 deleteCount 是 0,则不移除元素。这种情况下,至少应添加一个新元素。如果 deleteCount 大于start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。 - item1, item2, …(可选)
要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
源码:
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); } // Insert the arguments into the resulting array in // place of the deleted elements. 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 the deleted elements. return deleted_elements;}
还可以查看V8源码第660行:直达
或者开发文档:ECMA5.1文档
请注意
1.splice() 方法会直接对数组进行修改。slice() 不对数组进行修改,原数组不会改变。
2.splice() 返回值为被操作的值。slice() 以新的字符串返回被提取的部分。
3. [14, 3, 77].slice(1, 2) // [3]
[14, 3, 77].splice(1, 2) // [3, 77]
4.splice先执行删除操作,删除指定个数的元素,然后再插入elements(元素或数组),他的每次删除都涉及大量元素的重新排列,而在插入元素时引入队列来管理。所以splice()的效率不高
阅读全文
0 0
- JS中从Array.slice()与Array.splice()的底层实现原理分析区别
- JavaScript Array.splice()和slice()的区别
- JS的array.slice()和array.splice()的使用
- JS中slice,splice,split的区别
- js中split、splice、slice的区别
- JS中splice跟slice的区别
- js中splice和slice的区别
- javascript中Array的slice和splice方法的比较
- js利用Array.splice实现Array的insert/remove
- slice与splice的区别
- splice()与slice()的区别
- Actionscript3.0 Array splice slice
- JavaScript Array: slice vs splice
- JS中slice split和splice三者的区别
- Js中slite,splice,slice,join方法的用法区别
- splice与slice区别
- splice与slice的区别讲解
- slice,split,splice的区别与用法
- ios-程序中模拟GET和POST请求登录
- python基础--换行
- Linux进程(二)
- Android自定义view之ViewPager指示器——1
- redis--Sentinel
- JS中从Array.slice()与Array.splice()的底层实现原理分析区别
- HTTP协议理解
- 字母次数
- 如何编写测试计划
- 加农炮
- 观察者模式
- 41. First Missing Positive
- 自定义控件(三种)
- Ajax 知识地址总汇