js array函数 array在js中什么意思
javascript 的 array.prototype.slice 方法用于从现有数据库中提取指定索引范围的元素并生成新的数据库,且不会修改原数据库。1. 它接受两个可选参数begin和end,begin指定开始索引(默认为0,负数表示从补充倒数),end结束指定索引(不包含该索引元素,默认为补充倒数);2. 返回一个包含提取要素的新存储,原保持存储不变;3. 常用于数据库复制、子集导出、类数据库转换等场景;4. 在处理稀疏阵列时保留空槽,在处理非阵列对象时可以通过call或apply将其转换为备份。
JavaScript的Array.prototype.slice方法,说简单,就是一个用来从现有阵列中“切”出内容,然后生成一个全新的阵列的方法。它不会改变原始阵列,这很重要。解决方案
Array.prototype.slice()精髓方法提供了它的非破坏性(non-mutating)。它允许你基于一个集群的某个部分,创建一个浅拷贝(浅拷贝)的新集群。想象一下你有一条长长的文章,slice就是剪刀,你剪了一段,但原来的文章还在那里,并且没有变短。
这个方法的语法是arr.slice([begin[, end]])。
立即学习“Java免费学习笔记(深入)”;begin(任选):指定开始提取元素的索引。如果简单,slice会从索引0开始。如果是负数,它会从数组的复数开始计算,例如 -1 表示倒数第一个元素,-2 表示倒数第二个,以此类推。如果 begin 超出备份的容量,结果会是一个空备份。end(可选):指定结束元素的索引(不包含该索引处的元素)。如果结果,slice 会取出到备份的结果。如果是负数,同样从数据库队列计算。如果 end 小于或等于 begin,或者结果通常会是一个空备份(而不是 begin)也超出了)。
slice方法返回一个包含移除元素的新数据库。
看几个例子可能更直观:const originalArray = ['apple', 'banana', 'orange', 'grape', 'kiwi'];// 1. 复制完整一个队列 const fullCopy = originArray.slice();console.log(fullCopy); // ['apple', 'banana', 'orange', 'grape', 'kiwi']console.log(originalArray); // ['apple', 'banana', 'orange', 'grape', 'kiwi'] (原阵列未变)// 2. 从指定索引开始到 const fromIndex2 = originalArray.slice(2);console.log(fromIndex2); // ['orange', 'grape', 'kiwi']// 3.从指定索引开始到指定索引之前 const from1To3 = originArray.slice(1, 4); // 包含索引 1、2、3,不包含 4console.log(from1To3); // ['banana', 'orange', 'grape']// 4.负数使用索引 const lastTwo = originArray.slice(-2); // 从倒数第二个开始到 倒数console.log(lastTwo); // ['grape', 'kiwi']const middlePart = originArray.slice(-4, -1); // 从倒数第四个开始,到倒数第一个console.log(middlePart); // ['banana', 'orange', 'grape']// 5. begin 超出长度 constemptySlice = originalArray.slice(10);console.log(emptySlice); // []// 6. end 小于 beginconst anotherEmptySlice = originalArray.slice(3, 1);console.log(anotherEmptySlice); // []登录后复制slice和splice有什么区别?
我个人觉得,刚开始学JavaScript的时候,这俩名字就很容易让人犯迷糊,因为它们听起来太像了。但它们的功能和对原数组的影响简直是天壤之别的。
核心区别在于:slice是“切片”,它只负责提取,然后给你一份新的副本,原数据库不可用。而 splice“拼接”说或者“剪接”,它直接是在原数据库上动刀子,删除、或者添加替换元素可以,并且返回被删除的元素(如果删除了的话)。
看个对比:const arr1 = ['a', 'b', 'c', 'd', 'e'];const arr2 = ['a', 'b', 'c', 'd', 'e'];//使用切片 const slicedResult = arr1.slice(1, 4);console.log('slice结果:', slicedResult); // slice 结果: ['b', 'c', 'd']console.log('slice 后原备份:', arr1); // slice 后原备份: ['a', 'b', 'c', 'd', 'e'] (原备份不变)// 使用 spliceconst splicedResult = arr2.splice(1, 3, 'x', 'y'); //从索引1开始删除3个元素,并插入'x', 'y'console.log('splice 结果 (被删除的元素):', splicedResult); // splice 结果 (被删除的元素): ['b', 'c', 'd']console.log('splice 后原数据库:', arr2); // splice 后原数据库: ['a', 'x', 'y', 'e'] (原栈被修改了!)登录后复制
你看,slice就像是拍了张照片,原物还在;splice直接改造了原物。理解这个本质区别,用起来就不会冲突了。slice在哪些实际场景中特别有用?
slice方法在日常开发中有着非常广泛且实用的应用,尤其是在需要保持数据不变性(immutability)的场景下,它简直就是神器。
创建集群的浅拷贝: 这是最常见的用途之一。当你需要对一个数据进行操作,但又不影响原始数据流时,arr.slice()(不带参数)是最简洁的复制方式。这种函数式编程或者像React/Redux这样的状态管理库中非常重要,因为它们推崇不统计数据流。const originalData = [{id: 1}, {id: 2}];const newData = originalData.slice(); //得到一个新的数组,但内部对象仍然是引用newData[0].id = 100;console.log(originalData[0].id); // 100 (浅拷贝的特性:内部对象还是同一个引用)//如果要深拷贝,则需要JSON.parse(JSON.stringify(originalData)) 或 lodash.cloneDeep登录复制后
将类数组对象(Array-like)对象)转换为真正的磁盘:很多时候,我们会遇到一些长得像磁盘但不是真正磁盘的对象,比如函数内部的参数对象,或者DOM 返回操作的NodeList。它们有length属性和索引访问,但是没有Array.prototype上的方法。slice就可以派上用场了。
function sumAll() { //argsArray = Array.prototype.slice.call(arguments); // 或 [].slice.call(arguments) return argsArray.reduce((acc, val) =gt; acc val, 0);}console.log(sumAll(1, 2, 3, 4)); // 10// 假设document.querySelectorAll 返回一个 NodeList// const divs = document.querySelectorAll('div');// const divArray = Array.prototype.slice.call(divs);// 现在 divArray 就可以使用所有的数组方法了,复制后
这个技巧非常经典,尤其是在 ES6 普及之前,现在有了扩展接口 ...,起来更了 ([...arguments]),但可以理解 slice这种方法仍然很有价值。
备份的子集: 比如在分页功能中,你可能需要从一个大批量中取出当前页的数据;或者在显示有限列表时,只显示前N项。const allItems = Array.from({length: 100}, (_, i) =gt; `Item ${i 1}`);const pageSize = 10;const currentPage = 3; // 第三页 const startIndex = (currentPage - 1) * pageSize;const endIndex = startIndex pageSize;const itemsForCurrentPage = allItems.slice(startIndex, endIndex);console.log(itemsForCurrentPage); // ['Item 21', ..., 'Item 30']登录后复制
结合其他备份方法实现复杂逻辑:你可以先过滤一个备份,然后对结果切片取前几项,或者先切片一部分map。这种链式操作在数据处理中非常常见。slice 处理稀疏阵列或非阵列对象时表现如何?
这部分内容其实相当密集的,它揭示了切片在一些“非典型”场景下的行为。
处理稀疏阵列(Sparse Arrays):稀疏阵列是指那些阵列中存在“空槽”的阵列,比如[1, , 3]。当切片遇到稀疏阵列时,它会保留这些空槽。换句话说,新生成的阵列在对应位置上,依然是空的(空)。它不会去填充这些空缺,只是原样复制。
const稀疏Array = [1, , 3, 4, , 6];const slicedSparse =稀疏Array.slice(1, 5);console.log(slicedSparse); // [empty, 3, 4,empty]console.log(slicedSparse.length); // 4 (长度是正确的,但中间有空洞)登录后复制
这和map、forEach等方法跳过空槽的行为是一致的,体现了 JavaScript 对分布式磁盘的处理方式。
处理非磁盘对象(Array-like Objects):前面在“实际场景”中已经提到了,slice 可以通过 call 或 apply 方法作用于那些长度属性和索引元素的非磁盘对象。这种能力是 slice 的一个强大特性,使得能够“借用”磁盘的方法。 const myObject = { 0: 'hello', 1: 'world', length: 2, 2: 'extra' //即使有额外的属性,只要长度 限制了,slice也只看length范围内的};const newArray = Array.prototype.slice.call(myObject);console.log(newArray); // ['hello', 'world']console.log(Array.isArray(newArray)); // true//如果没有length属性,或者length为0,结果就是空 const anotherObject = { 0: 'test'};const emptyArray = Array.prototype.slice.call(anotherObject);console.log(emptyArray); // [] (因为没有 length 属性,或者说 length 默认为 0)const objWithNoLength = { a: 1, b: 2 };const resultNoLength = Array.prototype.slice.call(objWithNoLength);console.log(resultNoLength); // []登录后复制
这里就体现了JavaScript的灵活性,但也可能让人有点困惑的地方。它不会完成那些空缺,只是原样复制。而对那些长得像阵列但又不是阵列的家伙,slice简直就是它们的“变身术”,让它们瞬间拥有了阵列的强大能力。这个特性在处理 DOM集合或者自定义数据结构时候非常有用。
以上就是JavaScript的Array.prototype.slice方法是什么?怎么用?的详细内容,更多请关注乐哥常识网其他相关文章!