• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2025-04-04 20:40 Aet 隐藏边栏 |   抢沙发  2 
文章评分 1 次,平均分 5.0

文档

  1. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference

数组方法

添加/移除数组元素

  1. arr.push(...items) —— 从尾端添加元素
  2. arr.pop() —— 从尾端提取元素
  3. arr.shift() —— 从首端提取元素
  4. arr.unshift(...items) —— 从首端添加元素

splice

  1. 数组是对象,所以我们可以尝试使用 delete

  1. 元素被删除了,但数组仍然有 3 个元素,我们可以看到 arr.length == 3
    1. 这很正常,因为 delete obj.key 是通过 key 来移除对应的值
    2. 对于对象来说是可以的。但是对于数组来说,我们通常希望剩下的元素能够移动并占据被释放的位置
  2. splice可以做所有事情:添加,删除和插入元素
    1. 它从索引 start 开始修改 arr:删除 deleteCount 个元素并在当前位置插入 elem1, ..., elemN
    2. 最后返回被删除的元素所组成的数组

  1. 删除了 3 个元素,并用另外两个元素替换它们:

  1. splice 返回了被删除的元素所组成的数组:

  1. deleteCount 设置为 0splice 方法就能够插入元素而不用删除任何元素:

  1. 允许负向索引

slice

  1. 语法是:
    1. 会返回一个新数组,将所有从索引 startend(不包括 end)的数组项复制到一个新的数组
    2. startend 都可以是负数,在这种情况下,从末尾计算索引

  1. 也可以不带参数地调用它:arr.slice() 会创建一个 arr 的副本

concat

  1. 创建一个新数组,其中包含来自于其他数组和其他项的值
  2. 它接受任意数量的参数 —— 数组或值都可以
  3. 结果是一个包含来自于 arr,然后是 arg1arg2 的元素的新数组

  1. 通常,它只复制数组中的元素。其他对象,即使它们看起来像数组一样,但仍然会被作为一个整体添加:

  1. 如果类数组对象具有 Symbol.isConcatSpreadable 属性,那么它就会被 concat 当作一个数组来处理:此对象中的元素将被添加:

遍历:forEach

  1. 允许为数组的每个元素都运行一个函数

  1. 显示了数组的每个元素:

  1. 介绍了它们在目标数组中的位置:

indexOf/lastIndexOfincludes

  1. arr.indexOf(item, from) —— 从索引 from 开始搜索 item,如果找到则返回索引,否则返回 -1
  2. arr.includes(item, from) —— 从索引 from 开始搜索 item,如果找到则返回 true(译注:如果没找到,则返回 false

  1. 注意,indexOfincludes 使用严格相等 === 进行比较
    1. 所以,如果我们搜索 false,它会准确找到 false 而不是数字 0
  2. 方法 arr.lastIndexOfindexOf 相同,但从右向左查找

  1. 方法 includes 可以正确的处理 NaN
    1. 方法 includes 的一个次要但值得注意的特性是,它可以正确处理 NaN,这与 indexOf 不同:
    2. 这是因为 includes 是在比较晚的时候才被添加到 JavaScript 中的,并且在内部使用了更新了的比较算法

findfindIndex/findLastIndex

  1. 语法
    1. 有一个对象数组。我们如何找到具有特定条件的对象?

  1. 例如,我们有一个存储用户的数组,每个用户都有 idname 字段。让我们找到 id == 1 的那个用户:

  1. arr.findIndex方法(与 arr.find)具有相同的语法,但它返回找到的元素的索引,而不是元素本身。如果没找到,则返回 -1
  2. arr.findLastIndex方法类似于 findIndex,但从右向左搜索,类似于 lastIndexOf

filter

  1. find 方法搜索的是使函数返回 true 的第一个(单个)元素
  2. 如果需要匹配的有很多,我们可以使用 arr.filter(fn)
    1. 语法与 find 大致相同,但是 filter 返回的是所有匹配元素组成的数组:

转换数组:map

  1. arr.map方法是最有用和经常使用的方法之一
  2. 它对数组的每个元素都调用函数,并返回结果数组

重新排序:sort(fn)

  1. arr.sort方法对数组进行 原位(in-place) 排序,更改元素的顺序
    1. 原位是指在此数组内,而非生成一个新数组
  2. 它还返回排序后的数组,但是返回值通常会被忽略,因为修改了 arr 本身\
  3. 示例:
    1. 这些元素默认情况下被按字符串进行排序
    2. 从字面上看,所有元素都被转换为字符串,然后进行比较

  1. 要使用我们自己的排序顺序,我们需要提供一个函数作为 arr.sort() 的参数

  1. 使用 localeCompare for strings

颠倒顺序:reverse

  1. 用于颠倒 arr 中元素的顺序
    1. 它也会返回颠倒后的数组 arr

split

  1. 用“逗号后跟着一个空格”作为分隔符:

  1. split 方法有一个可选的第二个数字参数 —— 对数组长度的限制。如果提供了,那么额外的元素会被忽略
    1. 但实际上它很少使用:

  1. 调用带有空参数 ssplit(s),会将字符串拆分为字母数组:

join

  1. arr.join(glue)split 相反
    1. 它会在它们之间创建一串由 glue 粘合的 arr

reducereduceRight

  1. 当我们需要遍历一个数组时 —— 我们可以使用 forEachforfor..of
  2. 当我们需要遍历并返回每个元素的数据时 —— 我们可以使用 map
  3. arr.reduce方法和 arr.reduceRight方法和上面的种类差不多,但稍微复杂一点
    1. 它们用于根据数组计算单个值
    2. accumulator —— 是上一个函数调用的结果,第一次等于 initial(如果提供了 initial 的话)
    3. item —— 当前的数组元素
    4. index —— 当前索引
    5. arr —— 数组本身

  1. 通过一行代码得到一个数组的总和:
    1. 也可以省略初始值:
    2. 如果没有初始值,那么 reduce 会将数组的第一个元素作为初始值,并从第二个元素开始迭代

  1. 建议始终指定初始值

Array.isArray

  1. 数组是基于对象的,不构成单独的语言类型
    1. 所以 typeof 不能帮助从数组中区分出普通对象:

  1. 但是数组经常被使用,因此有一种特殊的方法用于判断:Array.isArray(value)
    1. 如果 value 是一个数组,则返回 true;否则返回 false

大多数方法都支持 “thisArg

  1. 几乎所有调用函数的数组方法 —— 比如 findfiltermap,除了 sort 是一个特例,都接受一个可选的附加参数 thisArg
    1. 上面的部分中没有解释该参数,因为该参数很少使用

  1. thisArg 参数的值在 func 中变为 this
    1. 例如,在这里我们使用 army 对象方法作为过滤器,thisArg 用于传递上下文(passes the context):

Iterable object(可迭代对象)

概述

  1. 可迭代(Iterable) 对象是数组的泛化
    1. 这个概念是说任何对象都可以被定制为可在 for..of 循环中使用的对象
  2. 数组是可迭代的
    1. 但不仅仅是数组。很多其他内建对象也都是可迭代的。例如字符串也是可迭代的

Symbol.iterator

  1. 例如,我们有一个对象,它并不是数组,但是看上去很适合使用 for..of 循环

  1. 为了让 range 对象可迭代(也就让 for..of 可以运行)我们需要为对象添加一个名为 Symbol.iterator 的方法(一个专门用于使对象可迭代的内建 symbol
    1. for..of 循环启动时,它会调用这个方法(如果没找到,就会报错)
      这个方法必须返回一个 迭代器(iterator) —— 一个有 next 方法的对象
    2. 从此开始,for..of 仅适用于这个被返回的对象
    3. for..of 循环希望取得下一个数值,它就调用这个对象的 next() 方法
    4. next() 方法返回的结果的格式必须是 {done: Boolean, value: any},当 done=true 时,表示循环结束,否则 value 是下一个值

  1. 注意可迭代对象的核心功能:关注点分离
    1. range 自身没有 next() 方法
    2. 相反,是通过调用 range[Symbol.iterator]() 创建了另一个对象,即所谓的“迭代器”对象,并且它的 next 会为迭代生成值
    3. 因此,迭代器对象和与其进行迭代的对象是分开的
  2. 从技术上说,我们可以将它们合并,并使用 range 自身作为迭代器来简化代码
    1. 现在 range[Symbol.iterator]() 返回的是 range 对象自身:它包括了必需的 next() 方法,并通过 this.current 记忆了当前的迭代进程
    2. 这样更短,对吗?是的。有时这样也可以
    3. 但缺点是,现在不可能同时在对象上运行两个 for..of 循环了:它们将共享迭代状态,因为只有一个迭代器,即对象本身
      但是两个并行的 for..of 是很罕见的,即使在异步情况下

字符串是可迭代的

  1. 数组和字符串是使用最广泛的内建可迭代对象
  2. 对于一个字符串,for..of 遍历它的每个字符:

  1. 对于代理对(surrogate pairs),它也能正常工作
    1. 译注:这里的代理对也就指的是 UTF-16 的扩展字符

显式调用迭代器

  1. 采用与 for..of 完全相同的方式遍历字符串,但使用的是直接调用
    1. 这段代码创建了一个字符串迭代器,并“手动”从中获取值
    2. 很少需要我们这样做,但是比 for..of 给了我们更多的控制权

可迭代(iterable)和类数组(array-like

  1. Iterable 如上所述,是实现了 Symbol.iterator 方法的对象
  2. Array-like 是有索引和 length 属性的对象,所以它们看起来很像数组
  3. 当我们将 JavaScript 用于编写在浏览器或任何其他环境中的实际任务时,我们可能会遇到可迭代对象或类数组对象,或两者兼有
    1. 例如,字符串即是可迭代的(for..of 对它们有效),又是类数组的(它们有数值索引和 length 属性)
  4. 但是一个可迭代对象也许不是类数组对象。反之亦然,类数组对象可能不可迭代
    1. 例如,上面例子中的 range 是可迭代的,但并非类数组对象,因为它没有索引属性,也没有 length 属性
    2. 下面这个对象则是类数组的,但是不可迭代:

  1. 可迭代对象和类数组对象通常都 不是数组,它们没有 pushpop 等方法

Array.from

  1. 可以接受一个可迭代或类数组的值,并从中获取一个“真正的"数组"
    1. 就可以对其调用数组方法了
    2. (*) 行的 Array.from 方法接受对象,检查它是一个可迭代对象或类数组对象,然后创建一个新数组,并将该对象的所有元素复制到这个新数组

  1. 如果是可迭代对象,也是同样:

  1. Array.from 的完整语法允许我们提供一个可选的“映射(mapping)”函数:
    1. 可选的第二个参数 mapFn 可以是一个函数,该函数会在对象中的元素被添加到数组前,被应用于每个元素,此外 thisArg 允许我们为该函数设置 this

  1. Array.from 将一个字符串转换为单个字符的数组:
    1. str.split 方法不同,它依赖于字符串的可迭代特性
    2. 因此,就像 for..of 一样,可以正确地处理代理对(surrogate pair

  1. 甚至可以基于 Array.from 创建代理感知(surrogate-aware)的slice 方法
    1. 也就是能够处理 UTF-16 扩展字符的 slice 方法

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享