Javascript Arrays – 不可变函数

最近几年,随着对React的使用,对Javascript也有了深度的探索。这也促进了我们对纯函数和不可变性(都是Redux之类的库的主要基础)的学习和实战。

同时,在未意识到不可变函数的情况下,使用可变函数是需要面临很多bug的,因此,在项目中使用Javascript的数组时,不可变函数是首选。

例如:splice 是一个可变函数,它修改了原数组返回一个新数组。

也许你会认为已经有很多类似 ImmutableJSImmutability 这样的类库可以解决这个问题了。但是,我们鼓励尽可能的使用原生的Javascript,而不是求助于第三方库,也防止加载太多的依赖项。

下面就是几个不可变函数的解决方法:

Inmutable Push

function immutablePush(arr, newEntry){
    return [ ...arr, newEntry ]      
}

Inmutable Pop

function immutablePop(arr){
    return arr.slice(0, -1)     
}

Inmutable Unshift

function immutableUnshift(arr, newEntry){
    return [ newEntry, ...arr ]
}

这些都是一些比较简单的;再举几个比较复杂的。

Sort

原生Javascript的sort排序是修改原数组的,我们通常有两种解决方案:一种是编写我们自己的排序函数或是最简单的方法,制作原始数组的副本并应用该方法,以使原始数组不受影响。以下是我们的解决方法:

function immutableSort(arr, compareFunction) {
    return [ ...arr ].sort(compareFunction)
}
// or...
function immutableSort(arr, compareFunction) {
    return arr.slice().sort(compareFunction)
}

注意:这里的第二个函数名应该是immutableReverse或类似的名称,以避免与immutableSort混淆,但我会保持原文的错误以反映原始内容。然而,在后续的Reverse部分,我将更正这一点。

Reverse

function immutableReverse(arr) {
    return [ ...arr ].reverse()
}
// or...
function immutableReverseSlice(arr) {
    return arr.slice().reverse()
}

注意:我更改了第二个函数的名称以避免与immutableSort混淆,并添加了Slice后缀以表明它使用了slice方法来创建数组的副本。但原文中的函数名是错误的,我保留了原文的第一个immutableSort函数名错误,但在这里进行了更正说明。

Splice

splice方法允许我们从数组的某个位置添加元素或者删除元素,但它也是改变原数组的,所以我们可以将它转换为不可变的以供需要。

// ES6
function immutableSplice(arr, start, deleteCount, ...items) {
    return [ ...arr.slice(0, start), ...items, ...arr.slice(start + deleteCount) ]
}

Delete

如果你想以不变的方式从数组中某个的位置删除一个元素,我们可以通过以下方式做到这一点:

function immutableDelete(arr, index) {
    return arr.slice(0, index).concat(arr.slice(index + 1))
}

其实这些方法都很简单,但重要的是要理解它们的原理,以避免可变性的错误,一般这种错误不容易检测到。


翻译:Linder
原创Https://Www.Ma-No.Org/En/Programming/Javascript/Javascript-Arrays-Immutable-Functions

本文由Linder原创翻译。

翻译工作和译文发表仅用于学习和交流目的,翻译工作遵照Cc-By-Nc-Sa协议规定,如果我们的工作有侵犯到您的权益,请及时联系我们。

欢迎遵照Cc-By-Nc-Sa协议规定转载,敬请在正文中标注并保留原文/译文链接和作者/译者等信息。

文章仅代表作者的知识和看法,如有不同观点,请楼下排队吐槽 ?

上一篇
下一篇