You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constm=newMap();consta=0/"",// NaN b=0/"",// NaN pz=+0,nz=-0;alert(a===b);// false alert(pz===nz);// true m.set(a,"foo");m.set(pz,"bar");alert(m.get(b));// foo alert(m.get(nz));// bar
constkey1={id: 1},key2={id: 2},key3={id: 3};// 使用嵌套数组初始化弱映射constwm1=newWeakMap([[key1,"val1"],[key2,"val2"],[key3,"val3"]]);alert(wm1.get(key1));// val1 alert(wm1.get(key2));// val2 alert(wm1.get(key3));// val3 // 初始化是全有或全无的操作// 只要有一个键无效就会抛出错误,导致整个初始化失败constwm2=newWeakMap([[key1,"val1"],["BADKEY","val2"],[key3,"val3"]]);// TypeError: Invalid value used as WeakMap key typeofwm2;// ReferenceError: wm2 is not defined // 原始值可以先包装成对象再用作键conststringKey=newString("key1");constwm3=newWeakMap([stringKey,"val1"]);alert(wm3.get(stringKey));// "val1"
constval1={id: 1},val2={id: 2},val3={id: 3};// 使用数组初始化弱集合constws1=newWeakSet([val1,val2,val3]);alert(ws1.has(val1));// true alert(ws1.has(val2));// true alert(ws1.has(val3));// true // 初始化是全有或全无的操作// 只要有一个值无效就会抛出错误,导致整个初始化失败constws2=newWeakSet([val1,"BADVAL",val3]);// TypeError: Invalid value used in WeakSet typeofws2;// ReferenceError: ws2 is not defined // 原始值可以先包装成对象再用作值conststringVal=newString("val1");constws3=newWeakSet([stringVal]);alert(ws3.has(stringVal));// true
Object 是 ECMAScript 中最常用的类型之一。
在对象字面量表示法中,属性名可以是字符串 或 数值。注意,数值属性会自动转换未字符串。
属性可以通过 点语法 来存取, 也可以通过 中括号 来存取属性。(使用中括号的主要优势是可以通过变量访问属性)
Array
创建数组:
let colors = new Array();
let colors = new Array(20)
;如:
let colors = ["red", "blue", "green"];
ES6+
用于创建数组的静态方法: from() 和 of()
from() 用于将 类数组结构 转换 为 数组实例。
of() 用于将一组参数 转换为 数组实例。
Array.from() 的第一个参数时一个类数组对象,即为任何可迭代的结构,或者有一个 length 属性 和 可索引元素的结构。
Array.from() 可以接收第二个 可选的映射函数 参数。就不用使用 Array.from().map() 这样了。
可以接收第三个可选参数, 用于指定 映射函数中 this 的值。(重写的 this 值在箭头函数中不适用)
替换之前的 Array.prototype.slice.call(arguments)
数组空位
创建空位数组:
ES6 将空位当成存在的 undefined 的元素
ES6之前:
数组索引
检测数组
使用 instanceof 操作符:
使用 instanceof 的问题是假定只有一个全局执行上下文。
迭代器方法
ES6 中,Array原型上 有 3 个用于检索数组内容的方法。
使用 ES6 的解构
复制和填充方法
ES6 +
都需要指定既有数组实例上的一个范围,包含开始索引,不包含结束索引。使用这个方法不会改变数组的大小
fill()静默忽略超出数组边界、零长度及方向相反的索引范围:
copyWithin()会按照指定范围浅复制数组中的部分内容,然后将它们插入到指
定索引开始的位置。
copyWithin()静默忽略超出数组边界、零长度及方向相反的索引范围
数组中 转换方法
栈方法
栈是一种后进先出(LIFO,Last-In-First-Out)的结构
数据项的插入(称为推入,push)和删除(称为弹出,pop)只在栈的一个地方发生,即栈顶。ECMAScript 数组提供了 push()和 pop()方法,以实现类似栈的行为。
push()方法接收任意数量的参数,并将它们添加到数组末尾,返回数组的最新长度。pop()方法则用于删除数组的最后一项,同时减少数组的 length 值,返回被删除的项。
队列方法
队列以先进先出(FIFO,First-In-First-Out)形式限制访问。队列在列表末尾添加数据,但从列表开头获取数据。
使用 shift()和 push(),可以把数组当成队列来使用。
排序方法
对元素重新排序:reverse()和 sort()。
sort()方法可以接收一个比较函数,用于判断哪个值应该排在前面。
比较函数接收两个参数,如果第一个参数应该排在第二个参数前面,就返回负值;如果两个参数相等,就返回 0;如果第一个参数应该排在第二个参数后面,就返回正值。
操作方法
concat()方法可以在现有数组全部元素基础上创建一个新数组。
打平数组参数的行为可以重写,方法是在参数数组上指定一个特殊的符号:Symbol.isConcatSpreadable。这个符号能够阻止concat()打平参数数组。相反,把这个值设置为 true 可以强制打平类数组对象
slice()用于创建一个包含原有数组中一个或多个元素的新数组。
slice()方法可以接收一个或两个参数:返回元素的开始索引和结束索引。
slice()返回从开始索引到结束索引对应的所有元素,其中不包含结束索引对应的元素。
不影响原始数组
如果结束位置小于开始位置,则返回空数组。
最强大的数组方法就属 splice()了
splice()的主要目的是在数组中间插入元素,但有 3 种不同的方式使用这个方法。
搜索和位置方法
ECMAScript 提供两类搜索数组的方法:按 严格相等 搜索和按 断言函数 搜索。
提供了 3 个严格相等的搜索方法:indexOf()、lastIndexOf()和 includes()
ES7 + includes()方法
这些方法都接收两个参数:要查找的元素和一个可选的起始搜索位置。
断言函数
每个索引都会调用这个函数。断言函数的返回值决定了相应索引的元素是否被认为匹配。
断言函数接收 3 个参数:元素、索引和数组本身。
find()和 findIndex()方法使用了断言函数。这两个方法都从数组的最小索引开始。find()返回第一个匹配的元素,
findIndex()返回第一个匹配元素的索引。这两个方法也都接收第二个可选的参数,用于指定断言函数内部 this 的值。
迭代方法
归并方法
数组提供了两个归并方法:reduce()和 reduceRight()
传给 reduce()和 reduceRight()的函数接收 4 个参数:上一个归并值、当前项、当前项的索引和数组本身。
定型数组
定型数组(typed array)是 ECMAScript 新增的结构,目的是提升向原生库传输数据的效率。
“TypedArray”类型,它所指的其实是一种特殊的包含数值类型的数组。
JavaScript 运行时使用这个类型可以分配、读取和写入数组。
这个数组可以直接传给底层图形驱动程序 API,也可以直接从底层获取到。
ArrayBuffer
Float32Array 实际上是一种“视图”,可以允许 JavaScript 运行时访问一块名为 ArrayBuffer 的预分配内存。ArrayBuffer 是所有定型数组及视图引用的基本单位。
ArrayBuffer()是一个普通的 JavaScript 构造函数,可用于在内存中分配特定数量的字节空间。
ArrayBuffer 一经创建就不能再调整大小。
可以使用 slice()复制其全部或部分到一个新实例中:
ArrayBuffer 某种程度上类似于 C++的 malloc(),但也有几个明显的区别。
不能仅通过对 ArrayBuffer 的引用就读取或写入其内容。要读取或写入 ArrayBuffer,就必须通过视图。
视图有不同的类型,但引用的都是 ArrayBuffer 中存储的二进制数据。
DataView
第一种允许你读写 ArrayBuffer 的视图是 DataView。这个视图专为文件 I/O 和网络 I/O 设计,其API 支持对缓冲数据的高度控制
DataView 对缓冲内容没有任何预设,也不能迭代。
必须在对已有的 ArrayBuffer 读取或写入时才能创建 DataView 实例。这个实例可以使用全部或部分 ArrayBuffer,且维护着对该缓冲实例的引用,以及视图在缓冲中开始的位置。
要通过 DataView 读取缓冲,还需要几个组件。
换。
DataView 对存储在缓冲内的数据类型没有预设。它暴露的 API 强制开发者在读、写时指定一个ElementType,然后 DataView 就会忠实地为读、写而完成相应的转换。
DataView 为上表中的每种类型都暴露了 get 和 set 方法,这些方法使用 byteOffset(字节偏移量)定位要读取或写入值的位置。
字节序
“字节序”指的是计算系统维护的一种字节顺序的约定。
DataView 只支持两种约定:大端字节序和小端字节序。
大端字节序也称为“网络字节序”,意思是最高有效位保存在第一个字节,而最低有效位保存在最后一个字节。小端字节序正好相反,即最低有效位保存在第一个字节,最高有效位保存在最后一个字节。
JavaScript 运行时所在系统的原生字节序决定了如何读取或写入字节,但 DataView 并不遵守这个约定。
对一段内存而言,DataView 是一个中立接口,它会遵循你指定的字节序。DataView 的所有 API 方法都以大端字节序作为默认值,但接收一个可选的布尔值参数,设置为 true 即可启用小端字节序。
边界情形
DataView 完成读、写操作的前提是必须有充足的缓冲区,否则就会抛出 RangeError:
DataView 在写入缓冲里会尽最大努力把一个值转换为适当的类型,后备为 0。如果无法转换,则抛出错误
定型数组
定型数组是另一种形式的 ArrayBuffer 视图
设计定型数组的目的就是提高与 WebGL 等原生库交换二进制数据的效率。
创建定型数组的方式包括读取已有的缓冲、使用自有缓冲、填充可迭代结构,以及填充基于任意类型的定型数组。
通过.from()和.of()也可以创建定型数组
定型数组的构造函数和实例都有一个 BYTES_PER_ELEMENT 属性,返回该类型数组中每个元素的大小:
如果定型数组没有用任何值初始化,则其关联的缓冲会以 0 填充:
定型数组支持如下操作符、方法和属性:
合并、复制和修改定型数组
定型数组同样使用数组缓冲来存储数据,而数组缓冲无法调整大小。因此,下列方法不适用于定型数组:
定型数组也提供了两个新方法,可以快速向外或向内复制数据:set()和 subarray()。
set()从提供的数组或定型数组中把值复制到当前定型数组中指定的索引位置:
subarray()执行与 set()相反的操作,它会基于从原始定型数组中复制的值返回一个新定型数组。
复制值时的开始索引和结束索引是可选的:
定型数组没有原生的拼接能力,但使用定型数组 API 提供的很多工具可以手动构建:
下溢和上溢
定型数组中值的下溢和上溢不会影响到其他索引,但仍然需要考虑数组的元素应该是什么类型。
定型数组对于可以存储的每个索引只接受一个相关位,而不考虑它们对实际数值的影响。
以下代码演示了如何处理下溢和上溢:
除了 8 种元素类型,还有一种“夹板”数组类型:Uint8ClampedArray,不允许任何方向溢出。
超出最大值 255 的值会被向下舍入为 255,而小于最小值 0 的值会被向上舍入为 0。
按照 JavaScript 之父 Brendan Eich 的说法:“Uint8ClampedArray 完全是 HTML5canvas 元素的历史留存。除非真的做跟 canvas 相关的开发,否则不要使用它。”
Map
ECMAScript 6 的新增特性,Map 是一种新的集合类型
使用 new 关键字和 Map 构造函数可以创建一个空映射:
顺序与迭代
映射实例可以提供一个迭代器(Iterator),能以插入顺序生成[key, value]形式的数组。可以通过 entries()方法(或者 Symbol.iterator 属性,它引用 entries())取得这个迭代器
因为 entries()是默认迭代器,所以可以直接对映射实例使用扩展操作,把映射转换为数组
forEach(callback, opt_thisArg) 传入的回调接收可选的第二个参数,这个参数用于重写回调内部 this 的值
keys()和 values()分别返回以插入顺序生成键和值的迭代器
选择 Object 还是 Map
WeakMap
ECMAScript 6 新增的“弱映射”(WeakMap)是一种新的集合类型
WeakMap 中的“weak”(弱),描述的是 JavaScript 垃圾回收程序对待“弱映射”中键的方式。
可以使用 new 关键字实例化一个空的 WeakMap:
弱映射中的键只能是 Object 或者继承自 Object 的类型,尝试使用非对象设置键会抛出TypeError。值的类型没有限制。
弱键
WeakMap 中“weak”表示弱映射的键是“弱弱地拿着”的。
只要键存在,键/值对就会存在于映射中,并被当作对值的引用,因此就不会被当作垃圾回收。
因为没有指向这个对象的其他引用,所以当这行代码执行完成后,这个对象键就会被当作垃圾回收。
不可迭代键
因为 WeakMap 中的键/值对任何时候都可能被销毁,所以没必要提供迭代其键/值对的能力。当然,也用不着像 clear()这样一次性销毁所有键/值的方法。WeakMap 确实没有这个方法。因为不可能迭代,所以也不可能在不知道对象引用的情况下从弱映射中取得值。即便代码可以访问 WeakMap 实例,也没办法看到其中的内容。
WeakMap 实例之所以限制只能用对象作为键,是为了保证只有通过键对象的引用才能取得值。如果允许原始值,那就没办法区分初始化时使用的字符串字面量和初始化之后使用的一个相等的字符串了。
使用弱映射
前提很明确:私有变量会存储在弱映射中,以对象实例为键,以私有成员的字典为值。
可以用一个闭包把 WeakMap 包装起来
Set
使用 new 关键字和 Set 构造函数可以创建一个空集合:
顺序与迭代
集合实例可以提供一个迭代器(Iterator),能以插入顺序生成集合内容。可以通过 values()方法及其别名方法 keys()(或者 Symbol.iterator 属性,它引用 values())取得这个迭代器
因为 values()是默认迭代器,所以可以直接对集合实例使用扩展操作,把集合转换为数组
修改集合中值的属性不会影响其作为集合值的身份
定义正式集合操作
某些 Set 操作是有关联性的,因此最好让实现的方法能支持处理任意多个集合实例
Set 保留插入顺序,所有方法返回的集合必须保证顺序。
尽可能高效地使用内存。扩展操作符的语法很简洁,但尽可能避免集合和数组间的相互转换能够节省对象初始化成本。
不要修改已有的集合实例。union(a, b)或 a.union(b)应该返回包含结果的新集合实例。
WeakSet
ECMAScript 6 新增的“弱集合”(WeakSet)是一种新的集合类型
WeakSet 中的“weak”(弱),描述的是 JavaScript 垃圾回收程序对待“弱集合”中值的方式。
可以使用 new 关键字实例化一个空的 WeakSet:
弱集合中的值只能是 Object 或者继承自 Object 的类型,尝试使用非对象设置值会抛出 TypeError。
弱值
不可迭代值
因为 WeakSet 中的值任何时候都可能被销毁,所以没必要提供迭代其值的能力。当然,也用不着像 clear()这样一次性销毁所有值的方法。WeakSet 确实没有这个方法。因为不可能迭代,所以也不可能在不知道对象引用的情况下从弱集合中取得值。即便代码可以访问 WeakSet 实例,也没办法看到其中的内容。
WeakSet 之所以限制只能用对象作为值,是为了保证只有通过值对象的引用才能取得值。如果允许原始值,那就没办法区分初始化时使用的字符串字面量和初始化之后使用的一个相等的字符串了。
使用弱集合
迭代与扩展操作
👌
The text was updated successfully, but these errors were encountered: