第6章 集合引用类型

6.1. Object

声明对象的两种方法:1. new(可以省略)和Object构造函数;2. 对象字面量(Object literal)

大括号有两种上下文:表达式上下文(expression context)和语句上下文(statement context)。

数值属性会自动转化为字符串。

在使用对象字面量定义对象的时候,并不会实际调用Object构造函数。

6.2. Array

创建数组的方式:

  1. Array构造函数:可以传一个数字——新建有这个长度的undefined的数组;或者传一些参数——会转化为array。使用Array构造函数的时候可以省略new操作符。
  2. Array字面量(array literal):不会调用Array构造函数
  3. Array.form():将类数组结构转化为数组:Array.from('abc')——任何可迭代的结构或者哟length属性和可索引元素的结构:Array.from({length: 10, '0': 1});另外还能接收第二个参数,类似于map函数:Array.from('abc'), (d) => d + '1'
  4. Array.of():将一组参数转化为数组:Array.of('a', 'b', 'c')

数组空位:使用数组字面量的时候可以用一组逗号来创建空位(hole)。最好别用,因为不同的方法可能忽略或者不忽略数组空位。

数组的length属性是可以修改的,通过修改该属性,可以在数组末尾添加或者删除元素。

数组是有最大长度限制的,最大允许$2^{32}$个元素。

检测数组的方法:1. instanceOf:如果有多个全局上下文,网页里有多个框架,则可能设计不同版本的Array构造函数,则该方法失效(比如多个window对象)。2. Array.isArray()

数组的其他方法:

  1. 迭代器方法:keys(), values(), entities()返回迭代器
  2. 复制和填充方法:copyWithIn(target, start, end)fill(value, start, end)(默认忽略过低、过高、反向索引)
  3. 转换方法:toString(), toLocaleString(), valueOf()(最后一个返回本身)
  4. 栈方法:push()(接收任意数量参数,返回length), pop()(返回pop的元素)
  5. 队列方法:shift(), unshift()(接收任意数量参数,返回length)
  6. 排序方法:reverse(), sort()——sort函数会对所有元素(包括Number)调用String()转型函数,然后升序排列;除非,传入一个比较函数。两者都会调用原数组,且返回原数组引用。
  7. 操作方法:
    1. concat()——可以传入一个数组,也可以传入一个非数组(后者直接push到元素列表),另外,数组可以指定Symbol.isConcatSpreadable来判断是否concat的时候会打平。
    2. slice()——得到sub-array,支持负值,反序返回空数组。
    3. splice():直接修改原数组,返回被删除的元素(或者空数组)。
      1. 删除:splice(start, number_of_elements_to_delete)
      2. 插入:splice(start, 0, elements_to_insert), for example, splice(1, 0, 'a', 'b', 'c')
      3. 替换:splice(start, number_of_elements_to_delete, elements_to_insert)
  8. 搜索和位置方法:
    1. 严格相等:indexOf(), lastIndexOf(), includes()
    2. 断言函数:find(), findIndex();必选参数:function(element, index, array),可选参数:thisArg:指定断言函数内部的this(但是不能是箭头函数哦,必须是function声明的)
  9. 迭代方法:
    1. every(), some():如果每一项都/有任何一项返回true,则返回true
    2. filter(), forEach(就它没有返回值), map()
  10. 归并方法:reduce(), reduceRight(),参数:prev, cur, index, array

6.3. 定型数组(Typed Array)

一些历史:WebGL的早期版本使用JavaScript Array导致性能很低,因为JavaScript Array数组和原生数组的精度不一致,前者是默认双精度浮点格式。 于是Mozilla为解决这个问题实现了CanvasFloatArray,然后它演变成了Float32Array

ArrayBuffer是所有定型数组及视图引用的基本单位。new ArrayBuffer(byteSize)

ArrayBuffer的方法:slice()

ArrayBuffer和C的malloc()的区别:

  1. malloc()分配失败会返回null空指针,ArrayBuffer会抛出错误
  2. malloc()会使用虚拟内存,ArrayBuffer不会
  3. malloc()不会初始化内存空间,ArrayBuffer会初始化为0
  4. malloc()需要配合着free()使用,ArrayBuffer不用手动释放

读写ArrayBuffer需要使用视图(view),有两种方法:DataView和ArrayBuffer View。

DataView读取有3个部分:

  1. ElementType: Int8, Uint8, Int16, Int32, Float32, Float64...这些,每一种类型都有getset方法,比如getInt8()
  2. 字节序(Big-endian and little-endian),set方法会默认使用大字节序,如果set方法的第三个参数是true,则使用小字节序。
  3. 边界情形:无法转换类型则抛出错误。

定型数组:

  1. 类型:Int32Array() ...
  2. 创建方式:
    1. new [类型](ArrayBuffer),比如new Int32Array(arrayBuffer)
    2. new [类型](数组长度)
    3. [类型].from(可迭代对象)
    4. [类型].of(多个参数)
  3. 定型数组支持大部分Array的方法,但是需要修改数组大小的方法是不支持的,比如concat, pop, push... 定型数组支持的新方法:set, subarray
  4. 数组元素上溢和下溢会自动转化成二补数(有符号),或者保留有效位(无符号)。
  5. Uint8ClampedArray可以自动转换成最大255, 最小0的值,除非做canvas开发否则不建议使用。

6.4. Map

6.5. WeakMap

6.6. Set

6.7. WeakSet

6.8. 迭代与扩展操作