影子的知识库

影子的知识库

  • 知识库
  • GitHub

›ES6

JVM系列

  • JVM内存区域
  • 对象创建-布局-访问
  • 内存溢出实战
  • 内存区域回收
  • 四大引用
  • 垃圾回收算法
  • HotSpot回收算法细节

Java系列

  • java注解
  • springboot请求参数绑定
  • springboot请求参数校验框架
  • YAML语法
  • 动态代理
  • classpath和java命令
  • springboot-aop编程
  • springboot统一异常处理
  • springboot数据库和事务
  • springboot拦截器
  • springboot中的web配置
  • docker的简单开发
  • springboot自动配置
  • 数据库的隔离级别
  • springboot监控
  • java类加载
  • java-agent的相关内容
  • 类加载器详解
  • java的SecurityManager
  • maven学习

Node

    JS 基础

    • 语法基础和数据类型
    • 数据类型转换
    • 语句 表达式 运算符
    • 变量与对象
    • 函数
    • 数据处理
    • 常用 API
    • 重点知识

    ES6

    • 块级作用域
    • 字符串和正则表达式
    • 函数
    • 对象
    • Symbol
    • Set和Map
    • 迭代器和生成器
    • 类
    • 数组
    • Promise

    Node 基础

    • 模块系统
    • package.json
    • 内置对象
    • npm脚本的使用
    • Buffer
    • Stream
    • 事件循环机制
    • 示例代码

    stream系列

    • 流的缓冲
    • 可读流
    • 可写流
    • 双工流和转换流
    • 自定义流

后期计划

  • 学习计划
  • 专题研究计划
Edit

本文内容

Array.of()

这个方法实际上就是说,将传入的参数构造成一个数组

let arr = Array.of(3, '2');
console.log(arr.length); // 2
console.log(arr[0]); // 3
console.log(arr[1]); // 2
let arr = Array.of(3);
console.log(arr.length); // 1
console.log(arr[0]); // 3
console.log(arr[1]); // undefined

这个其实跟我们自己写数组字面量是一样的,只不过是一种函数的方式,可以将这个方法传递给其它函数来构造数组

Array.from()

这个方法接收一个可迭代对象或者类数组对象(具有数字下标属性、length属性的对象,例如 arguments 对象),返回一个数组。

function doSomething() {
    let args = Array.from(arguments);
}

也可以再传入一个转换函数,将可迭代对象或者类数组对象里的每一项元素经过一个转换

function doSomething() {
    let args = Array.from(arguments, value => value + 1, this);
}

这里就是将每个参数加 1 ,然后转换成数组

第三个参数是转换函数里的 this 值,我们可以不传递这个对象

find 和 findIndex

这两个方法都接收 2 个参数,一个是用于查找的回调函数,一个是回调函数绑定的 this 值(可选)

回调函数接收的参数如下

  • 数组中的元素值
  • 该元素的下标值
  • 数组本身

与 map 的回调的参数是一样的

如果回调函数返回 true,则表示找到了,否则继续迭代,直到遍历完成了整个数组。

如果找到了匹配的值,find 方法将会返回该值,findIndex 方法将会返回该值的下标

如果没有找到匹配的值,find 方法将会返回 undefined,findIndex 方法将会返回 -1

let nums = [1, 2, 3, 4];
console.log(nums.findIndex(value => {
    return value === 8;
})); // -1
console.log(nums.find(value => {
    return value === 8;
})); // undefined
console.log(nums.findIndex(value => {
    return value === 3;
})); // 2
console.log(nums.find(value => {
    return value === 3;
})); // 3

fill

这个方法是在数组中填充值的

let nums = [1, 2, 3, 4];
nums.fill(1);
console.log(nums); // [ 1, 1, 1, 1 ]

如果只想填充一部分值,也可以传入开始下标和结束下标(包左不包右)

let nums = [1, 2, 3, 4, 5, 6, 7];
nums.fill(1, 2, 5); // 下标 2 到下标 4,也就是 3,4,5 被替换成 1
console.log(nums.join(',')); // 1,2,1,1,1,6,7

不传入结束下标,则是将开始下标开始的地方全部替换

如果下标是负值,例如 -1,那么会被当成 array.length - 1

copyWithin

let nums = [1, 2, 3, 4, 5, 6, 7];
console.log(nums.copyWithin(2, 1).join(',')); // 1,2,2,3,4,5,6

这个方法实际上是一个数组的移位操作

nums.copyWithin(2, 1) 表示:将数组从下标为 1 的地方开始,覆盖数组从下标为 2 开始的地方,最后的效果就是下标从 1 开始的地方,全部往右边移动覆盖了一样

我们可以传入第三个参数,用来控制想要重写的元素的数量

数组缓冲区

说白了,就是终于支持了控制单个字节的能力。一个数组缓冲区就是一块连续的内存,也就是一组连续的字节

let buffer = new ArrayBuffer(10); // 创建 10 个字节的缓冲区
console.log(buffer.byteLength); // 10
let newBuffer = buffer.slice(4, 6); // 切片,从原来的缓冲区截取 4 和 5 下标的字节
console.log(newBuffer.byteLength); // 2

slice 是切片方法,常规操作

视图

我们可以从缓冲区创建视图,说白了视图就是缓冲区的一个片段

let buffer = new ArrayBuffer(10); // 创建 10 个字节的缓冲区
let view = new DataView(buffer, 3); // 从第四个字节开始创建视图
console.log(view.byteLength); // 7

视图创建时可以传入第三个参数,表示截取的视图长度

视图有以下只读属性

  • buffer:表示创建视图的那个数组缓冲区(原始的那一整块缓冲区)
  • byteOffset:视图相对于缓冲区的偏移量,也就是我们创建视图的第二个参数
  • byteLength:视图的长度

读取和写入数据

我们通过视图可以读取和写入数据,以下是读取和写入 int8 和 uint8 的方法

  • getInt8(byteOffset, littleEndian):读取 byteOffset 后的 int8 类型
  • setInt8(byteOffset, value, littleEndian):设置 byteOffset 处的 int8 类型
  • getUint8(byteOffset, littleEndian):读取 byteOffset 后的 uint8 类型
  • setUint8(byteOffset, value, littleEndian):设置 byteOffset 处的 uint8 类型

littleEndian 是布尔值,表示是否按照小端进行读取

这里的 API 也有读取和写入 32 或者 64 位浮点数的,只是换了后面的类型名称而已,不一一列举了

let buffer = new ArrayBuffer(2);
let view = new DataView(buffer);
view.setInt8(0, 5);
view.setInt8(1, -1);
console.log(view.getInt8(0)); // 5
console.log(view.getInt8(1)); // -1
console.log(view.getInt16(0)); // 1535

可以看出来,就是常规的缓冲区操作,主要是弥补了之前 JavaScript 操作字节的缺陷

特定类型的视图(定型数组)

上面的视图是个通用的视图,我们可以读取和写入任何类型。但是实际中,我们可能仅仅是需要写入和读取某种特定类型。(就像是 netty 里的 ByteBuf、LongBuf、IntBuf 等)

有以下的定型数组

  • Int8Array
  • Uint8Array
  • Int16Array
  • Uint16Array
  • Int32Array
  • Uint32Array
  • Float32Array
  • Float64Array
  • Uint8ClampedArray 8位无符号整数(强制转换),与 Uint8Array 大致相同,区别是如果值小于 0 或者大于 255,Uint8ClampedArray 会分别将其转换成 0 或者 255,例如将 -1 转成 0,将 300 转成 255(也就是只转成这两个值的一个)

创建定型数组

第一种,跟创建通用视图差不多

let buffer = new ArrayBuffer(10);
let view1 = new Int8Array(buffer, 5, 2);

第二种,自己创建一个全新的缓冲区

let ints = new Int16Array(3);
console.log(ints.byteLength); // 6
console.log(ints.length); // 3

这里的传入的 3,表示我们想要创建的缓冲区应该包含 3 个 Int16,因此打印的 ints.byteLength = 6,每个 Int16 占用 2 个字节,一共 3 个所以是 6。而 length 表示的是 Int16 个数量

第三种方式,是传入其它的一些对象,将这些对象作为缓冲区的输入源,来创建一个定型数组,支持以下参数

  • 一个定性数组:将这个定型数组进行内存复制,复制到一个新的我们创建的定型数组中
  • 一个可迭代对象:调用对象的迭代器,将元素插入到新生成的定型数组中
  • 一个数组:跟上面一样,将数组元素插到定型数组中
  • 一个类数组对象:与数组一样
let ints = new Int32Array([1, '2']);
console.log(ints.byteLength); // 8
console.log(ints.length); // 2
console.log(ints[0]); // 1
console.log(ints[1]); // 2

定型数组的访问就跟普通数组一样

元素大小

定型数组有个属性,表示数组中每个元素的大小(字节数量)

  • BYTES_PER_ELEMENT
console.log(Uint8Array.BYTES_PER_ELEMENT); // 1
console.log(Uint16Array.BYTES_PER_ELEMENT); // 2
console.log(Uint32Array.BYTES_PER_ELEMENT); // 4

与普通数组的差异

  • 定型数组不继承 Array,使用 Array.isArray() 将返回 false
  • 定型数组赋值不存在的下标时,将会被忽视

说白了,定型数组更像是一个固定了长度、元素类型的数组

Last updated on 11/8/2020
← 类Promise →
  • Array.of()
  • Array.from()
  • find 和 findIndex
  • fill
  • copyWithin
  • 数组缓冲区
    • 视图
    • 读取和写入数据
    • 特定类型的视图(定型数组)
    • 创建定型数组
    • 元素大小
    • 与普通数组的差异
影子的知识库
Docs
Getting Started (or other categories)Guides (or other categories)API Reference (or other categories)
Community
User ShowcaseStack OverflowProject ChatTwitter
More
BlogGitHub
Copyright © 2020 Cen ZhiPeng