百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

JavaScript 中的 4 种新方法指南Array.

zhezhongyun 2025-04-11 09:45 61 浏览

JavaScript 中的 4 种新方法指南Array.prototype

Array其实和Python中的l列表list的操作用非常像

JavaScript 语言标准的最新版本是 ECMAScript 2023,这是第 14 版。此更新包括原型上的新方法。Array

我将指导您了解本文中突出的四种新方法,包括它们在稀疏数组和类数组对象中的行为。如果你喜欢编写JavaScript程序的声明式、函数式风格,那么你将大饱口福。

潜入:

  • 保留没有任何突变的原始阵列重要吗?
  • toReversed() 方法
  • toSorted() 方法
  • toSpliced(start, deleteCount, ...项)方法
  • with(index, value) 方法

保留没有任何突变的原始阵列重要吗?

四种新数组方法的一个共同主题是专注于不改变原始数组,而是返回一个全新的数组。您可能想知道,为什么这种行为很重要?

一般来说,不修改数据有很多优点,这四种新的数组方法就证明了这一点。这些好处不仅限于数组,而是扩展到所有 JavaScript 对象。

尽管有很多好处,但下面概述了一些最重要的好处:

  • 纯函数:在函数式编程中,纯函数是在给定相同输入时始终产生相同输出的函数:它们没有任何副作用,并且它们的行为是可预测的。当你不修改数据时,使用这个函数式心智模型是理想的选择,这四种新的数组方法是一个很好的补充。
  • 可预测的状态管理:创建状态对象(或数组)的新副本通过消除意外更改并使用新副本表示特定时间点的数据,使状态管理更具可预测性。这简化了大规模状态管理,并总体上改进了有关状态管理的推理
  • 更改检测:像 React 这样的框架通过比较状态或 props 对象的两个副本来识别任何更改并相应地呈现用户界面,从而使用简化的更改检测。使用这些方法检测变化变得更加简单,因为我们可以在任何给定时刻比较两个对象以识别任何变化。

方法toReversed()

该方法与经典方法相似,但有明显的区别。 反转数组中的元素,而不改变原始数组。toReversed()reverse()toReversed()

考虑以下水果阵列:

const fruits = ["apple", "orange", "banana"]

现在,反向与:fruits.reverse()

// Reverse the array 
const result = fruits.reverse()
console.log(result) 

// ['banana', 'orange', 'apple']

console.log(fruits)
// ['banana', 'orange', 'apple']
//  original array is mutated

使用 ,原始数组发生突变。reverse()

要反转数组而不改变它,我们可以使用如下所示的方法:toReversed()

// Reverse the array 
const result = fruits.toReversed()
console.log(result) 

// ['banana', 'orange', 'apple']

console.log(fruits)
// ["apple", "orange", "banana"] 
//  original array is preserved

瞧!

如果您使用的是最新版本的当前浏览器(如 Chrome),则可以访问浏览器控制台并测试本文中提供的代码示例:

在浏览器控制台中尝试该方法toReversed

稀疏数组的行为

为了快速复习,稀疏数组是没有顺序元素的数组。例如,请考虑以下事项:

const numbers = [1,2,3]
// Assign an item to index 11
numbers[11] = 12

console.log(numbers)
// [1, 2, 3, empty × 8, 12]

在上面的示例中, 有八个空项目槽。 是一个稀疏数组。现在,回到 。这如何与稀疏数组一起工作?numbersnumberstoReversed()

toReversed()从不返回稀疏数组。如果原始阵列有空插槽,则它们将返回为 。undefined

考虑调用下面的数组:toReversed()numbers

const numbers = [1,2,3]
// Assign an item to index 11
numbers[11] = 12

numbers.toReversed()
// [12, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, 3, 2, 1]

正如预期的那样,所有空插槽都作为数组项值返回。undefined



类数组对象的行为

即使专门存在于原型上,它也可以在类似数组的对象上调用。toReversed()Array

类似数组的对象通常具有属性和(可选)具有整数索引名称的属性。字符串对象是类数组对象的一个示例。length

该函数首先读取调用它的对象的属性,然后从末尾到开头遍历对象的整数键,这意味着从 to .它将每个属性的值添加到新数组的末尾,然后返回该数组。toReversed()lengthlength - 10

让我们试一试。考虑在字符串上的错误应用:toReversed()

const s = "Ohans Emmanuel"

// call `toReversed` directly on the string
s.toReversed()

//Uncaught TypeError: s.toReversed is not a function

即使字符串对象是一个类似数组的对象,这个程序也是错误的:我们不能以这种方式调用它,因为原型上不存在。string.toReversed()toReversedstring

但是,我们可能会使用如下所示的方法:call()

const s = "Ohans Emmanuel"

// Array.prototype.toReversed.call(arrayLike)
Array.prototype.toReversed.call(s)

//['l', 'e', 'u', 'n', 'a', 'm', 'm', 'E', ' ', 's', 'n', 'a', 'h', 'O']

一个自我构造的、类似数组的对象怎么样?请考虑以下示例:

// Has a length property and integer index property.
const arrayLike = {
 length: 5,
 2: "Item #2"
}

如果这是一个标准数组,它将是一个稀疏数组,即长度为五,第二个索引中的值。

考虑调用此内容的结果:toReversed

console.log(Array.prototype.toReversed.call(arrayLike))

// [undefined, undefined, 'Item #2', undefined, undefined]

该函数生成一个反向数组,而不创建稀疏数组。正如预期的那样,空插槽返回为 。toReversed()undefined

方法toSorted()

.toSorted()是经典方法的对应物。.sort()

您可能已经猜到了,与 不同,不会改变原始数组。考虑以下基本排序操作:.sort().toSorted().sort()

const list = [1, 5, 6, 3, 7, 8, 3, 7]
//Sort in ascending order 
const result = list.sort()

console.log(result)
// [1, 3, 3, 5, 6, 7, 7, 8]
console.log(list)
// [1, 3, 3, 5, 6, 7, 7, 8]

如上所示,对数组进行就地排序,从而改变数组。现在,考虑与以下相同的情况:sort()toSorted()

const list = [1, 5, 6, 3, 7, 8, 3, 7]
// Sort in ascending order 
const result = list.toSorted()

console.log(result)
// [1, 3, 3, 5, 6, 7, 7, 8]
console.log(list)
// [1, 5, 6, 3, 7, 8, 3, 7]

如上所示,返回一个元素排序的新数组。toSorted()



请注意,保留与 相同的语法。例如,我们可以指定一个定义排序顺序的函数,例如。toSorted()sort()list.toSorted(compareFn)

请考虑以下示例:

const list = [1, 5, 6, 3, 7, 8, 3, 7]
//Sort the array in descending order 
list.toSorted((a,b) => a < b ? 1 : -1)
// [8, 7, 7, 6, 5, 3, 3, 1]

稀疏数组的行为

空插槽将始终返回为 。事实上,它们被视为值为 .但是,不会为这些插槽调用 ,它们将始终位于返回数组的末尾。
undefinedundefinedcompareFn

考虑以下示例,其中包含第一个插槽为空的数组:

// Note the empty initial slot 
const fruits = [, "apple", "orange", "banana"]

console.log(fruits.toSorted())

// ['orange', 'banana', 'apple', undefined]

此行为与初始值为 .请考虑以下示例:undefined

const fruits = [undefined, "apple", "orange", "banana"]

console.log(fruits.toSorted())

// ['orange', 'banana', 'apple', undefined]

另外,请注意,空插槽(或插槽)将始终移动到返回数组的末尾,无论它们在原始数组中的位置如何。undefined

请考虑以下示例:

// empty slot is in index 2
const fruits = ["apple", "orange", , "banana"]

console.log(fruits.toSorted())

// returned last 
// ['orange', 'banana', 'apple', undefined]

// undefined value is in index 2

const otherFruits = ["apple", "orange", undefined , "banana"]

console.log(otherFruits.toSorted())

// returned last 
// ['orange', 'banana', 'apple', undefined]

类数组对象的行为

当函数与对象一起使用时,它将首先读取对象的属性。然后,它将从头到尾收集对象的整数键,即从 to .对它们进行排序后,它将在新数组中返回相应的值。toSorted()lengththis0length - 1

请考虑以下带有字符串的示例:

const s = "Ohans Emmanuel"

// Array.prototype.toSorted.call(arrayLike)
Array.prototype.toSorted.call(s)
(14) [' ', 'E', 'O', 'a', 'a', 'e', 'h', 'l', 'm', 'm', 'n', 'n', 's', 'u']

请考虑以下示例,其中包含一个构造的类似数组的对象:

// Has a length property and integer index property.
const arrayLike = {
 length: 5,
 2: "Item #2"
10: "Out of bound Item" // This will be ignored since the length is 5
}

console.log(Array.prototype.toSorted.call(arrayLike))
// ['Item #2', undefined, undefined, undefined, undefined]

方法toSpliced(start,deleteCount,...items)

.toSpliced()是经典方法的对应物。与我们介绍的其他新方法一样,与 ..splice()toSpliced().splice()

的语法与 相同,如下所示:toSpliced.splice

toSpliced(start)
toSpliced(start, deleteCount)
toSpliced(start, deleteCount, item1)
toSpliced(start, deleteCount, item1, item2, itemN)

使用经典 添加新的数组项,如下所示:.splice()

const months = ["Feb", "Mar", "Apr", "May"] 
// Insert item "Jan" at index 0 and delete 0 items
months.splice(0, 0, "Jan")

console.log(months) 
//  ['Jan', 'Feb', 'Mar', 'Apr', 'May']

splice()插入新的数组项并改变原始数组。要在不改变原始数组的情况下创建新数组,请使用 。toSpliced()

考虑将上面的示例重写为使用 :toSpliced()

const months = ["Feb", "Mar", "Apr", "May"] 
// Insert item "Jan" at index 0 and delete 0 items
const updatedMonths = months.toSpliced(0, 0, "Jan")

console.log(updatedMonths)
// ['Jan', 'Feb', 'Mar', 'Apr', 'May']
console.log(months)
// ['Feb', 'Mar', 'Apr', 'May']

toSpliced()返回一个新数组而不改变原始数组。请注意两者的语法如何相同。toSpliced()splice()

稀疏数组的行为

toSpliced()从不返回稀疏数组。因此,空插槽将返回为 .undefined

请考虑以下示例:

const arr = ["Mon", , "Wed", "Thur", , "Sat"];
// Start at index 1, and delete 2 items
console.log(arr.toSpliced(1, 2)); 

// ['Mon', 'Thur', undefined, 'Sat']

类数组对象的行为

对于类似数组的对象,获取对象的长度,读取所需的整数键,并将结果写入新数组:toSplicedthis

const s = "Ohans Emmanuel"

// Start at index 0, delete 1 item, insert the other items
console.log(Array.prototype.toSpliced.call(s, 0, 1, 2, 3));

// [2, 3, 'h', 'a', 'n', 's', ' ', 'E', 'm', 'm', 'a', 'n', 'u', 'e', 'l']

方法with(index,value)

数组方法特别有趣。首先,考虑用于更改特定数组索引值的括号表示法:.with()

const favorites = ["Dogs", "Cats"]
favorites[0] = "Lions"

console.log(favorites)
//(2) ['Lions', 'Cats']

使用括号表示法,原始数组总是改变的。 实现在特定索引中插入元素的相同结果,但不会改变数组。相反,它会返回一个带有替换索引的新数组。.with()

让我们重写初始示例以使用:.with()

const favorites = ["Dogs", "Cats"]
const result = favorites.with(0, "Lions")

console.log(result)
// ['Lions', 'Cats']
console.log(favorites)
// ["Dogs", "Cats"]

稀疏数组的行为

with()从不返回稀疏数组。因此,空插槽将返回为:undefined

const arr = ["Mon", , "Wed", "Thur", , "Sat"];
arr.with(0, 2)
// [2, undefined, 'Wed', 'Thur', undefined, 'Sat']

类数组对象的行为

与其他方法类似,读取对象的属性。然后,它读取对象的每个正整数索引(小于 )。访问这些时,它会将其属性值保存到返回数组索引中。with()lengththislength

最后,在返回的数组上设置调用签名中的 and。请考虑以下示例:indexvaluewith(index, value)

const s = "Ohans Emmanuel"

// Set the value of the first item
console.log(Array.prototype.with.call(s, 0, "F"));

// ['F', 'h', 'a', 'n', 's', ' ', 'E', 'm', 'm', 'a', 'n', 'u', 'e', 'l']

结论

ECMAScript 标准在不断改进,利用它的新功能是个好主意。继续利用 、、 并创建更具声明性的 JavaScript 应用程序。
toReversedtoSortedtoSplicedwith

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...