《JS原理、方法与实践》- ES6新增对象(上篇)

Symbol Symbol是ES6中新增的一种类型,其含义是符号、标志,它的作用是每调用一次都会返回一个独一无二的返回值,我们可以将此返回值作为对象的属性,这样就不会与原有的属性重名了。即使传入相同的参数,Symbol方法也会返回不同的值。Symbol只能作为方法使用,而不是使用new去创建对象。另一个作用是使用Symbol.iterator作为属性来定义遍历器。 代码示例: var obj = {}; var abc1 = Symbol('abc'); var abc2 = Symbol('abc'); obj[abc1] = 'hello'; console.log(obj[abc1]); // hello console.log(obj[abc2]); // undefined console.log(obj[Symbol('abc')]); // undefined console.log(abc1 === abc2); // false 容器对象_Set Set是一种集合类型,类似于Array数组,但与Array存在两点不同:Set中的元素不可以重复;Set中的元素没有序号。 Set对象的属性 Set的prototype属性对象有一个size属性和8个方法:add、clear、delete、has、keys、entries、forEach和values。 代码示例: var setTest = new Set(); // add:对象添加元素,且返回一个Set对象 setTest.add('a').add('b').add('c'); for (var v of setTest) { console.log(v); // a, b, c } // has: 判断Set对象中是否包含某个元素 console.log(setTest.has('a')); // true // values: 获取Set的值 for (var v of setTest.values()) { console.log(v); // a, b, c } // keys: 与map对应,set的名-值相等 for (var v of setTest.keys()) { console.log(v); // a, b, c } // entries: 获取名-值对, 与map对应。 for (var v of setTest.entries()) { console.log(v); // ['a', 'a'],['b', 'b'], ['c', 'c'] } // 遍历Set对象 setTest.forEach((v) => console.log(v)); // a,b,c // delete: 删除Set对象的某一个元素 setTest.delete('a'); setTest.forEach((v) => console.log(v)); // b,c // clear:清空Set对象 setTest.clear(); setTest.forEach((v) => console.log(v)); // 无输出 容器对象_Map Map对象一种名值对结构。它的作用与对像不同,功能比较单一,只是保存数据的一种容器。虽然对象objct也是保存名值对,但有所不同。 如果Map的value是function类型,那么在function的方法体中Map不可以作为this使用。 如果对象的属性名全是对象,则会转换为字符串来使用(Symbol)除外,而如果Map的key是对象,则不需要转换,可以直接使用。 代码示例一: let obj = new Object(); let map = new Map(); obj.name = 'zzh'; obj.logName = function() { console.log(`name is ${this.name}`); } map.set('name', 'zzh'); map.set('logName', function() { console.log(`name is ${this.name}`); }); obj.logName(); // name is zzh map.get('logName')(); // name is map.logName(); // error: Uncaught TypeError: map.logName is not a function 代码示例二: var key1 = new Set([1,2,3]); var key2 = new Set([2,3,4]); var obj = new Object(); var map = new Map(); obj[key1] = 'value'; console.log(obj[key1]); // value console.log(obj[key2]); // value console.log(obj[new Set()]); // value // obj[key1]: [object Set], // obj[key2]: [object Set], // obj[new Set()]: [object Set] console.log(`obj[key1]: ${key1.toString()}, obj[key2]: ${key2.toString()}, obj[new Set()]: ${(new Set()).toString()}`); map.set(key1, 'value'); console.log(map.get(key1)); // value console.log(map.get(key2)); // undefined Map有一个size属性和9个方法:get, set, has, clear, delete, keys, values, entries, forEach。 Set的prototype属性对象有一个size属性和8个方法:add、clear、delete、has、keys、entries、forEach和values。 代码示例: var mapTest = new Map(); // set:对象添加元素,且返回一个Map对象 mapTest.set('a', 97).set('b', 98).set('c', 99); // ["a",97],["b",98],["c",98] for (var v of mapTest) { console.log(v); } // get: 根据key,查询该key对应的value console.log(mapTest.get('a')); // 97 // has: 判断Map对象中是否包含某个元素 console.log(mapTest.has('a')); // true // values: 获取Map的值 for (var v of mapTest.values()) { console.log(v); // 97,98, 99 } // keys: 遍历Map的key for (var v of mapTest.keys()) { console.log(v); // a, b, c } // entries: 获取名-值对 for (var v of mapTest.entries()) { console.log(v); // ['a', 97],['b', 98], ['c', 99] } // 遍历Map对象 mapTest.forEach((v) => console.log(v)); // 97,98,99 // delete: 删除Map对象的某一个元素 mapTest.delete('a'); mapTest.forEach((v) => console.log(v)); // 98,99 // clear:清空Map对象 mapTest.clear(); mapTest.forEach((v) => console.log(v)); // 无输出 WeakSet和WeakMap WeakSet和WeakMap是弱化了的Set和Map,具体说,就是垃圾回收器不会关注元素保存在WeakSet或WeakMap中所产生的以用。换句话说,在WeakSet或者WeakMap中保存的对象,或者在其他地方已经没有引用,垃圾回收器就可能回收它们所占用的内存,而不会考虑WeakSet和WeakMap中的引用,这样做可以有效避免内存泄漏的问题。 WeakSet和WeakMap在使用上跟Set和Map的区别主要是:WeakSet中的元素和WeakMap中的key都只能是对象类型(WeakMap的value可以是任意类型);WeakSet和WeakMap都没有size属性,都没有clear方法,都不可以遍历所包含的元素。 WeakSet的prototype一共有三个方法: add, has, delete WeakMap的prototype一共有四个方法:get, set, has, delete 缓存对象 ES6中新增了缓存类型,相关的对象一共有三个:ArrayBuffer、TypedArray和DataView。使用缓存进行操作的速度更快,缓存主要适用于对大量二进制数据的操作。 ArrayBuffer就像一个蓄水池,TypedArray就像水盆、水桶等多种盛水的工具,每种工具的大小都是确定的,而DataView则像一种可以随便改变大小的容器,可以更加灵活的使用蓄水池中的水。 ArrayBuffer只是用来保存数据,但不可以自己操作数据;TypedArray和DataView只是操作缓存数据的工具,他们本身并不存储数据。 ArrayBuffer var buffer = new ArrayBuffer(16); 缓存对象有一个byteLength属性和一个slice方法。byteLength表示缓存包含的字节数,slice方法可以提取出自己的一部分来创建一个新的缓存。slice方法有两个参数:start和end,start表示从那个字节开始提取,end表示提取到第几个字节,即提取的起始字节和结束字节,如果省略,则start默认为0,end默认为原始缓存所包含的字节数。 代码示例: var buffer = new ArrayBuffer(16); var buffer1 = buffer.slice(); var buffer2 = buffer.slice(5); var buffer3 = buffer.slice(5, 10); console.log(buffer.byteLength); // 16 console.log(buffer1.byteLength); // 16 console.log(buffer2.byteLength); // 11 console.log(buffer3.byteLength); // 5 slice方法所创建的缓存是新的缓存,即新的内存区域,而不是指向原来的内存地址,因此这里创建的4个缓存都是相互独立的,操作它们时不会相互影响。 TypedArray %TypedArray%(length) %TypedArray%(typedArray) %TypedArray%(object) %TypedArray%(buffer [,byteOffset[,length]]) 这里的%TypedArray%代表具体的类型数组对象,TypedArray作为对象的时候自身有两个方法:from和of,这两个方法都可以返回相应的TypedArray对象。from方法的参数可以遍历的对象类型,而of方法的参数直接用每个元素自身。 代码示例: var u8 = Uint8Array.from(new Set([1,3,5,7,9])); var i8_1 = Int8Array.from([1,3,5,7,9]); var i8_2 = Int8Array.of('1','3','5','7','9'); console.log(u8[3]); // 7 console.log(i8_1[3]); // 7 console.log(i8_2[3]); // 7 TypedArray创建出来的对象实例时操作缓存数据最重要的对象,它主要使用TypedArray的prototype属性对象中的属性实际操作。TypedArray的prototype属性对象一共有5个对象属性(包含直接量)和24个方法。5个对象属性分别是:constructor,buffer,byteOffset,byteLength和length。 DataView DataView可以截取ArrayBuffer中的一块内存来使用,DataView跟TypedArray的区别在于DataView并没有固定的格式,操作比TypedArray更加方便。 如果觉得文章写得还行,请点个赞。如果想与我进一步交流,可以关注我的公众号或者加我的微信。 个人微信 公众号_前端微说.jpg

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):