简体   繁体   English

什么时候(如果有的话)你会在 Javascript 中使用拼接而不是切片? (最佳实践)

[英]When (if ever) would you use splice instead of slice in Javascript? (best practices)

I've been learning about functional programming concepts.我一直在学习函数式编程概念。 One of the core concepts I've read is the importance of limiting the number of functions that modify an external variable to avoid unexpected potential bugs later down the road.我读过的核心概念之一是限制修改外部变量的函数数量的重要性,以避免以后出现意外的潜在错误。 With that in mind, the material I've been reading has recommended the use of slice over splice as slice outputs a new array without modifying the existing one, where splice will modify the existing array.考虑到这一点,我一直在阅读的材料建议使用 slice over splice 作为 slice 输出一个新数组而不修改现有数组,其中 splice 将修改现有数组。

Considering that you can do everything with slice that you can do with splice (given it takes a couple extra lines of code), when would you ever use splice over slice to modify an array?考虑到你可以用 slice 做所有你可以用 splice 做的事情(考虑到它需要几行额外的代码),你什么时候会使用 splice over slice 来修改数组? I'm wondering what kinds of scenarios I should consider using the splice method in. My main considerations are that splice may be more memory or CPU efficient to call when dealing with large arrays, since it just removes the value without having to store a "before" and "after" variable holding both sections of the array surrounding the value you wish to remove and then concatenating them back together.我想知道在哪种情况下我应该考虑使用拼接方法。我的主要考虑是拼接可能在处理大型 arrays 时调用效率更高,因为它只是删除值而不必存储“ before" 和 "after" 变量包含数组的两个部分,围绕您要删除的值,然后将它们连接在一起。 Also, it sounds like it could be more memory and CPU inefficient to use slice and would become even more of a bad idea, the larger the array is (a linear function of increased computational power used).此外,听起来可能更多 memory 和 CPU 使用切片效率低下,并且会变得更加糟糕,阵列越大(使用增加的计算能力的线性 function)。 But, perhaps my considerations are wrong or there are other cases I haven't thought of.但是,也许我的考虑是错误的,或者还有其他我没有想到的情况。 Any feedback is more than welcome.任何反馈都非常受欢迎。 I'm just trying to gain a deeper understanding of when the "pure functions" (functions that don't modify external variableS) concept is not applicable or isn't best use.我只是想更深入地了解“纯函数”(不修改外部变量的函数)概念何时不适用或不是最佳用途。

Here's an example of how I see slice as functionally capable of doing everything splice can:这是一个示例,说明我如何看待 slice 在功能上能够做任何 splice 可以做的事情:

 array = [1,2,3,4,5]; //using the splice method array.splice(3,1); // array is now [1,2,3,5] //using the slice method function replaceSplice(arr){ let sliceBefore = arr.slice(0,3); let sliceAfter = arr.slice(4); let modifiedArray = sliceBefore.concat(sliceAfter); } replaceSplice(array); // returns a new array called modifiedArray with the values [1,2,3,5]

With .slice , you're creating two copies of the array and then merging them.使用.slice ,您将创建数组的两个副本,然后将它们合并。 That's not very optimal, .splice on the other hand can be as fast as the underlying array implementation is.这不是很理想,另一方面, .splice可以与底层数组实现一样快。

Additionally in general, it's usually better to have methods that do what they say, even if there's an alternative.此外,一般来说,即使有替代方法,也最好有方法按照他们所说的去做。 Both .slice and .splice could be reimplemented using a simple for loop, but both are nice to have for various purposes. .slice.splice都可以使用简单for循环重新实现,但两者都可以用于各种目的。

splice is mutating existing array whereas slice creates a shallow copy of the array. splice 正在改变现有数组,而 slice 创建数组的浅表副本。 Use splice when you want to add/delete items from the original array.当您想从原始数组中添加/删除项目时,请使用 splice。 Use slice when you want to copy the array.当你想复制数组时使用切片。

In old js days slice was used to copy arguments into an array在旧 js 时代,切片用于将 arguments 复制到数组中

function () {
  typeof arguments.map; // => 'undefined'
  var copy = [].slice.call(arguments);
  typeof arguments.map; // => 'function'
}

You can't insert items in the array with slice, but you can do it with splice.您不能使用切片在数组中插入项目,但可以使用拼接来完成。 Example from MDN :来自MDN的示例:

var months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// inserts at index 1
console.log(months);
// expected output: Array ['Jan', 'Feb', 'March', 'April', 'June']

months.splice(4, 1, 'May');
// replaces 1 element at index 4

Use like push像推一样使用

months.splice(months.length, 0, 'May');
// expected output: Array ['Jan', 'March', 'April', 'June', 'May']

Choosing whether to use mutation or not can depend on different factors.选择是否使用突变可以取决于不同的因素。 But in general, try to avoid mutation in code.但总的来说,尽量避免代码中的突变。 Immutable code is less error-prone, easy to test and produces fewer side effects.不可变代码不易出错、易于测试并且产生的副作用更少。

So I have an application written in PHP that naturally uses JS on the front end.所以我有一个用 PHP 编写的应用程序,它在前端自然使用 JS。 This app allows a user to query the students within a school and district.此应用程序允许用户查询学校和学区内的学生。 So the flow goes: choose your district, that sends an ajax call to the server to retrieve the schools associated with that district.流程如下:选择您的学区,向服务器发送 ajax 调用以检索与该学区关联的学校。 This then populates the next select field with the appropriate schools based on the district filter.然后,这会根据地区过滤器使用适当的学校填充下一个 select 字段。 Then based on the school selected, it sends an ajax request to get all the students in that school.然后根据选择的学校,它发送一个 ajax 请求以获取该学校的所有学生。 The app sends back an array of schools and students that i loop over in the options.该应用程序发回我在选项中循环的一系列学校和学生。 So if I had a check box on each to hide a particular school or hide a particular student for some reason, I could use splice to remove it from the array without another query to the server.因此,如果我在每个复选框上都有一个复选框来隐藏特定学校或出于某种原因隐藏特定学生,我可以使用 splice 将其从数组中删除,而无需再次查询服务器。 The only reason i'd feel comfortable doing this is because I can just regenerate that array with a new query.我觉得这样做很舒服的唯一原因是因为我可以使用新查询重新生成该数组。 I personally have never had a use case for splice on a hardcoded array that wasn't generated from a query of some kind.我个人从来没有在不是从某种查询中生成的硬编码数组上拼接的用例。 I'm curious to see if other users have a solid use case for it myself.我很想知道其他用户自己是否有可靠的用例。 Interesting question.有趣的问题。

Considering that you can do everything with slice that you can do with splice (given it takes a couple extra lines of code), when would you ever use splice over slice to modify an array?考虑到你可以用 slice 做所有你可以用 splice 做的事情(考虑到它需要几行额外的代码),你什么时候会使用 splice over slice 来修改数组?

First of all slice can't do what splice does and splice can't do what slice does.首先slice不能做splice做的事情,而splice也不能做slice做的事情。 The important difference is that splice modifies the array in-place and cannot create a shallow copy while slice can't modify the array in-place and always creates a shallow copy.重要的区别在于splice就地修改数组并且不能创建浅拷贝,而slice不能就地修改数组并且总是创建浅拷贝。

A good example of both would be having a function that accepts an array as parameter and does some sort of transformation:两者的一个很好的例子是拥有一个接受数组作为参数并进行某种转换的 function:

 function someTransformation(array) { // Slice the array to create a shallow copy, if you don't do this // the input array will be modified which the caller might not // expect. array = array.slice(); for (let i = array.length; i >= 0; --i) { // Since a copy of the array is used we can modify the array however // we want without modifing the original. Splice let us insert an // element around each element of the original array with ease. array.splice(i, 0, '-'); } return array; } const array = [1,2,3,4,5]; console.log(someTransformation(array)); console.log(array);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM