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

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

wptr33 2025-05-05 19:04 23 浏览

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

相关推荐

MySQL进阶五之自动读写分离mysql-proxy

自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...

Postgres vs MySQL_vs2022连接mysql数据库

...

3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?

引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...

一文由浅入深带你完全掌握MySQL的锁机制原理与应用

本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...

验证Mysql中联合索引的最左匹配原则

后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...

MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)

目录1.索引基础...

你会看 MySQL 的执行计划(EXPLAIN)吗?

SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...

MySQL 从入门到精通(四)之索引结构

索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...

mysql总结——面试中最常问到的知识点

mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...

mysql总结——面试中最常问到的知识点(2)

首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...

MySQL基础全知全解!超详细无废话!轻松上手~

本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...

深入剖析 MySQL 中的锁机制原理_mysql 锁详解

在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...

Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析

引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...

MySQL基础篇:DQL数据查询操作_mysql 查

一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...

MySql:索引的基本使用_mysql索引的使用和原理

一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...