汇合援用类型
1. Object(详见c08 p205)
适宜存储,在应用程序间替换数据
创立实例:
- 显式构造函数
- 字面量——>不会调用构造函数(代码更少、更有封装感)
函数:大量参数的状况下,适宜用:<u>命名参数(必选)+对象字面量封装多个(可选)参数</u>的模式
2. Array
有序,动静大小
2.1 创立实例:
- 构造函数
- 字面量——>不会调用构造函数
-
两个办法
from(类数组, (可选)映射函数, (可选)映射函数中this指定的对象)
of() 参数->数组
2.2 empty元素:
- forEach(疏忽),for(当成undefined解决),map(会跳过不解决),join(视为空串)
- ES6新增办法视其为undefined
- 行为不统一,性能隐患
2.3 索引相干:
- index 超过最大索引的解决
- length 不只读(可变大或变小)
2.4 检测是否数组:
Array.isArray(obj) 兼容框架间不同版本的构造函数
2.5 迭代器办法:
keys()、values() (默认)、entries()。
2.6 填充:
- fill(arg1, arg2, arg3) arg1:填充值
- copyWithin(arg1, arg2, arg3) arg1:填充的索引
arg2 \ arg3 : 开始、完结索引
2.7 转换
- toString() 各个元素转换后拼接
- toLocaleString()
- valueOf() 数组自身
- join(分隔符)
2.8 模仿数据结构
- 栈LIFO: push(接管任意数量的参数,返回数组的最新长度)、pop(返回出栈元素)
- 队FIFO: push、shift(返回出队元素)
- 反队:unshift(接管任意数量的参数,返回数组的最新长度)、pop
2.9 排序
- sort((a,b)=> {…}) 参数函数返回值1:ab须要调换,否则不须要。会扭转数组自身
- reverse() 将数组元素反向排序。 扭转数组自身。不够灵便
都返回调用它们的数组的援用。
2.10 在旧数组上建新数组
- concat(),可传多个参数
- slice(开始索引, 完结索引(不蕴含,可选))
- splice(开始索引, 长度(>=0,可选), N个插入的元素(可选)):扭转原数组,返回被删除元素的数组
2.11 搜寻
按严格相等(===)(要查找的元素、可选的起始搜寻地位)、按断言函数
- 严格相等:indexOf、lastIndexOf。返回要查找的元素在数组中的地位,或者-1
- includes:返回布尔值。ES7新增。
-
断言函数:find、findIndex。都从数组的最小索引开始。可选第二个参数为指定断言函数外部this的指向。返回第一个匹配元素的元素/索引
断言函数接管3个参数:元素、索引和数组自身。返回的值决定了相应索引的元素是否被认为匹配。
2.12迭代
- every((item, index, array)=>…)、some((item, index, array)=>…):全副合乎函数/局部合乎函数
- filter(产生新数组):过滤。某一些是否应该蕴含在它返回的数组中。
-
一一迭代
- forEach。相当于应用for循环遍历数组
- map(新数组):映射。适宜用于创立一个与原始数组元素一一对应的新数组。
2.13 归并
- reduce(fn(pre, cur, index, array),[prev])
- reduceRight
返回运行到最初归并函数的返回值
const a = ["foo", "bar", "baz", "qux"];
const aKeys = a.keys(),
aValues = a.values(),
aEntries = a.entries();
console.log( a.values === a[Symbol.iterator] ); // true
console.log( Array.from(aKeys) ); // [ 0, 1, 2, 3 ]
console.log( Array.from(aValues) ); // [ 'foo', 'bar', 'baz', 'qux' ]
console.log( Array.from(aEntries) ); // [ [ 0, 'foo' ], [ 1, 'bar' ], [ 2, 'baz' ], [ 3, 'qux' ] ]
for(const [idx, element] of a.entries()) {
console.log( idx, element );
}
// 0 foo
// 1 bar
// 2 baz
// 3 qux
for(const e of a) {
console.log( e );
}
// Array
// copyWithin
let ints,
reset = () => ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
reset();
ints.copyWithin( 5 );
console.log( ints );
// [
// 0, 1, 2, 3, 4,
// 0, 1, 2, 3, 4
// ]
reset();
ints.copyWithin( 0, 5 );
console.log( ints );
// [
// 5, 6, 7, 8, 9,
// 5, 6, 7, 8, 9
// ]
reset();
ints.copyWithin( 4, 0, 3 );
console.log( ints );
// [
// 0, 1, 2, 3, 0,
// 1, 2, 7, 8, 9
// ]
reset();
ints.copyWithin( 2, 0, 6 );
console.log( ints );
// [
// 0, 1, 0, 1, 2,
// 3, 4, 5, 8, 9
// ]
reset();
ints.copyWithin( -4, -7, -5 );
console.log( ints );
// [
// 0, 1, 2, 3, 4,
// 5, 3, 4, 8, 9
// ]
reset();
// Array
// empty
let a2 = [1, 2, undefined];
a2.length = 4;
a2[4] = null;
a2.forEach(item => console.log(item));
// 1
// 2
// undefined
// null
for(let i =0 ;i<a2.length;i++){
console.log(a2[i]);
}
// 1
// 2
// undefined
// undefined
// null
3. 定型数组 TypedArray
一种非凡的蕴含数值类型的数组
目标:晋升向原生库传输数据的效率。
应用场景:WebGL。能够间接传给底层图形驱动程序API。
3.1 ArrayBuffer
ArrayBuffer(字节数):调配的内存(供定型数组及视图援用的根本单位)
c27 p793
3.2 定型数组和视图
- 视图:DataView(buf)
-
定型数组:无奈调整大小
- .set(数组, 开始索引(可选))
- .subarray(开始索引, 完结索引(可选))
function typedArrayConcat(typedArrayConstructor, ...typedArray) {
const numElements = typedArray.reduce((x,y) => (x.length || x) + y.length);
const resultArray = new typedArrayConstructor(numElements);
let currentOffset = 0;
typedArray.forEach(x => {
resultArray.set(x, currentOffset);
currentOffset += x.length;
});
return resultArray;
}
const concatArray = typedArrayConcat(Int32Array,
Int8Array.of(1, 2, 3),
Int16Array.of(4, 5, 6),
Float32Array.of(7, 8, 9));
console.log( concatArray );
// Int32Array(9) [
// 1, 2, 3, 4, 5,
// 6, 7, 8, 9
// ]
console.log( concatArray instanceof Int32Array ); // true
4. Map
Map(可迭代构造)
key能够是任意类型,(function也可)
-
基本操作
- .set(key, value)
- .get(key), .has(key)
- .delete(key)(返回是否有对应键的布尔值)、.clear()(革除所有键值对)
- size、有序
- key比照的SameValueZero的问题:NaN与NaN、+0与-0
- 迭代器办法:keys() 、values()、entries()(默认)
-
与Object比照
- Map内存利用率高、插入更快、删除更快
- Object 查找更快(有优化)
const m1 = new Map([
["key1", "value1"],
["key2", "value2"],
["key3", "value3"]
]);
console.log( m1 ); // Map(3) { 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }
console.log( m1.size ); // 3
const m2 = new Map({
[Symbol.iterator]: function *() {
yield ["key1", "value1"];
yield ["key2", "value2"];
yield ["key3", "value3"];
}
});
console.log( m2 ); // Map(3) { 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }
console.log( m2.size ); // 3
const m = new Map();
console.log( m.has("firstName") ); // false
console.log( m.get("firstName") ); // undefined
console.log( m.size ); // 0
m.set( "firstName", "Matt" )
.set( "lastName", "Frisble" );
console.log( m.has("firstName") ); // true
console.log( m.get("firstName") ); // Matt
console.log( m.size ); // 2
m.delete( "firstName" );
console.log( m.has("firstName") ); // false
console.log( m.get("firstName") ); // undefined
console.log( m.size ); // 1
m.clear();
console.log( m.has("firstName") ); // false
console.log( m.has("lastName") ); // false
console.log( m.size ); // 0
console.log( 'order=========' );
console.log( m.entries === m[Symbol.iterator] ); // true
for (let pair of m1.entries()) {
console.log( pair );
}
// [ 'key1', 'value1' ]
// [ 'key2', 'value2' ]
// [ 'key3', 'value3' ]
for (let pair of m1) {
console.log( pair );
}
// [ 'key1', 'value1' ]
// [ 'key2', 'value2' ]
// [ 'key3', 'value3' ]
console.log( ...m1 ); // [ 'key1', 'value1' ] [ 'key2', 'value2' ] [ 'key3', 'value3' ]
m1.forEach((value, key) => console.log( `${key}->${value}` ));
// key1->value1
// key2->value2
// key3->value3
5. WeakMap
键只能为对象类型或子类型;
无迭代(键不可迭代);
利于垃圾回收(键在其余中央无援用就回收);
应用场景:
1)(伪)公有变量
2)DOM元素映射(不影响回收垃圾)
const wm = new WeakMap();
class User {
constructor(id) {
this.idProperty = Symbol('id');
this.setId(id);
console.log( 'constructor' )
}
setId(id) {
this.setPrivateProperty(this.idProperty, id);
}
setPrivateProperty(property, value) {
const privateMembers = wm.get(this) || {};
privateMembers[property] = value;
if(!wm.get(this)) wm.set(this, privateMembers);
}
getId() {
return this.getPrivateProperty(this.idProperty);
}
getPrivateProperty(property) {
return wm.get(this)[property];
}
}
const user = new User(123);
console.log( user.getId() ); // 123
user.setId(456);
console.log( user.getId() ); // 456
console.log( wm.get(user)[user.idProperty] ); // 456
const PackedUser = (()=> {
const wm = new WeakMap();
class PackedUser {
constructor(id) {
this.idProperty = Symbol('id');
this.setId(id);
}
setId(id) {
this.setPrivateProperty(this.idProperty, id);
}
setPrivateProperty(property, value) {
const privateMembers = wm.get(this) || {};
privateMembers[property] = value;
if(!wm.get(this)) wm.set(this, privateMembers);
}
getId() {
return this.getPrivateProperty(this.idProperty);
}
getPrivateProperty(property) {
return wm.get(this)[property];
}
}
return PackedUser;
})();
const packedUser = new PackedUser(123);
console.log( packedUser.getId() ); // 123
6. Set
Set(可迭代对象)
- 不反复值
-
基本操作
- add(value)
- has(value)
- delete(value)(返回是否有对应值的布尔值)、clear()清空集合
- size
- 迭代器办法:keys() 、values()(默认)、entries()
-
扩大Set实现
交加、并集、差集、对称差集、笛卡尔积、幂集
class XSet extends Set {
union(...sets) {
return XSet.union(this, ...sets);
}
intersection(...sets) {
return XSet.intersection(this, ...sets);
}
difference(set) {
return XSet.difference(this, set);
}
symmetricDifference(set) {
return XSet.symmetricDifference(this, set);
}
cartesianProduct(set) {
return XSet.cartesianProduct(this, set);
}
powerSet() {
return XSet.powerSet(this);
}
// 返回两个或多个汇合的并集
static union(a, ...bSets) {
const unionSet = new XSet(a);
for (const b of bSets) {
for (const bValue of b) {
unionSet.add(bValue);
}
}
return unionSet;
}
// 返回两个或多个汇合的交加
static intersection(a, ...bSets) {
const intersectionSet = new XSet(a);
for (const aValue of intersectionSet) {
for (const b of bSets) {
if(!b.has(aValue)) {
intersectionSet.delete(aValue);
}
}
}
return intersectionSet;
}
// 返回两个汇合的差集 a-b
static difference(a, b) {
const differenceSet = new XSet(a);
for (const bValue of b) {
if(a.has(bValue)) {
differenceSet.delete(bValue);
}
}
return differenceSet;
}
// 返回两个汇合的对称差集 (a-b)+(b-a) | a和b的并集-a和b的交加
static symmetricDifference(a, b) {
return a.union(b).difference(a.intersection(b));
}
// 返回两个汇合(数组对模式)的笛卡尔积
// 必须返回数组汇合,因为笛卡尔积可能蕴含雷同值的对
static cartesianProduct(a, b) {
const cartesianProductSet = new XSet();
for (const aValue of a) {
for (const bValue of b) {
cartesianProductSet.add([aValue, bValue]);
}
}
return cartesianProductSet;
}
// 返回一个汇合的幂集
static powerSet(a) {
const powerSet = new XSet().add(new XSet());
for (const aValue of a) {
for (const set of new XSet(powerSet)) {
powerSet.add(new XSet(set).add(aValue));
}
}
return powerSet;
}
}
let xSet = new XSet().add(1);
console.log( xSet.powerSet() ); // XSet(2) [Set] { XSet(0) [Set] {}, XSet(1) [Set] { 1 } }
xSet.add(2);
console.log( xSet.powerSet() );
// XSet(4) [Set] {
// XSet(0) [Set] {},
// XSet(1) [Set] { 1 },
// XSet(1) [Set] { 2 },
// XSet(2) [Set] { 1, 2 }
// }
7. WeakSet
值只能为对象类型或子类型
无迭代(值不可迭代)
利用垃圾回收
应用场景:
1)DOM元素汇合:DOM元素被从页面上删除(且无其余援用)即可回收
8. 迭代与扩大
有默认迭代器的类型:
values():Array、定型数组、Set
entries()——Map
主动调用的中央:for-of循环、扩大操作符
发表回复