九、数据类型 Symbol
/* * Symbol 数据类型 概念: Symbol 提供一个独一无二的值 * */ { let a1 = Symbol(); let a2 = Symbol(); console.log(a1===a2,a1,a2); //false let a3 = Symbol.for('a3'); //*Symbol.for 会检查window下是否存在 'a3' let a4 = Symbol.for('a3'); console.log(a3===a4); //true } { //用法 let a1 = Symbol.for('abc'); let obj = { [a1]:'123', //独一无二的key 值 'abc':345, 'c':'456' } console.log('obj',obj); //{abc: 345, c: "456", Symbol(abc): "123"} for(let [key,value] of Object.entries(obj)){ console.log(key,value); //abc 345 c 456 // * for in/of 取不到Symbol类型key值 } Object.getOwnPropertySymbols(obj).forEach(function (item) { console.log(obj[item]); //123 可以拿到Symbol类型的key 但拿不到常规的key值 }) Reflect.ownKeys(obj).forEach(function (item) { //可以拿到Symbol类型的key和常规的key console.log('ownKeys',obj[item]); //ownKeys 345 ownKeys 456 ownKeys 123 }) }
十、数据结构 Map()、Set()、WeakMap()、WeakSet()
/* * ES6中的数据结构 Set() WeakSet() Map() WeakMap() * */ { let list = new Set(); list.add(5); list.add(7); console.log('size', list.size) //获取 长度 size 2 } { let arr = [1, 2, 3, 4, 5]; let list = new Set(arr); console.log('size', list.size) //size 5 } { let list = new Set(); list.add(1); list.add(2); list.add(1); //往Set 数据类型中添加重复的值 不会报错,只是不会生效 console.log('list', list) //Set(2) {1, 2} } { /* 利用Set数据类型的特性去重 **Set 在转换元素的的时候不会进行数据类型的转换 */ let arr = [1, 2, 3, 1, 5, '2', 4]; let list = new Set(arr); console.log('unique', list); //Set(6) {1, 2, 3, 5, "2", 4} 字符串‘2’和数值2同时存在 } /* * Set实例方法 add delete clear has * */ { let arr = ['add', 'delete', 'clear', 'has']; let list = new Set(arr); console.log('has', list.has('add')); //true console.log('delete', list.delete('add'), list); //Set(3) {"delete", "clear", "has"} console.log('clear', list.clear(), list) //Set(0) {} } /* * 对Set数据结构的遍历 * */ { let arr = ['add', 'delete', 'clear', 'has']; let list = new Set(arr); for (let key of list.keys()) { console.log('keys', key); //keys add keys delete keys clear keys has } for (let v of list.values()) { console.log('values', v); //values add values delete values clear values has } for (let [k,v] of list.entries()) { console.log('entries', k, v); //entries add add entries delete delete ... } list.forEach(function (item) { console.log(item); //add, delete, clear, has }) } /* * WeakSet 支持的数据类型必须是 *对象 * WeakSet中的对象都是弱引用 不会和垃圾回收机制挂钩 * * WeakSet 不能遍历,是因为成员都是弱引用,随时可能消失,遍历不能保证成员的存在。 * 可能刚刚遍历结束,成员就取不到了。WeakSet的一个用处是存储DOM节点,而不用担心这些节点从文档移除时,会引起内存的泄露。 * WeakSet结构有以下方法 * WeakSet.add(value):向WeakSet实例添加一个新成员。 * WeakSet.delete(value):删除WeakSet实例指定成员。 * WeakSet.has(value):返回一个布尔值,表示某个值是否在WeakSet实例中。 * */ { let weakList = new WeakSet(); let arg = {}; weakList.add(arg); //weakList.add(1); //Invalid value used in weak set } /* * Map数据结构 Map的key值可以为任意类型 * */ { let map = new Map(); let arr = [1, 2, 3]; map.set(arr, 456) console.log('map', map) //Map(1) {Array(3) => 456} 使用数组作为key } { let map = new Map([['a', 123], ['b', 456]]); console.log('map args', map); //Map(2) {"a" => 123, "b" => 456} console.log('size', map.size); //size 2 console.log('get', map.get('a')); //get 123 console.log('delete', map.delete('a'), map); //delete true Map(1) {"b" => 456} console.log('clear', map.clear(), map); //clear undefined Map(0) {} } /* * WeakMap WeakMap 接受的key值必须为对象 其他同WeakSet * */ { let weakMap = new WeakMap(); let o = {}; weakMap.set(o, 123); console.log('weakMap', weakMap.get(o)); //weakMap 123 } /* * Set 和 Array * */ { let set = new Set(); let arr = []; //增 set.add({'t': 1}); arr.push({'t': 1}); console.log('ser-arr', set, arr); //查 let set_exist = set.has({t: 1}); //false 引用类型的地址不同 let arr_exist = arr.find(item=>item.t); //改 set.forEach(item=>item.t ? item.t = 2 : ''); arr.forEach(item=>item.t ? item.t = 2 : ''); console.log('set-arr-modify', set, arr); //删 set.forEach(item=>item.t ? set.delete(item) : '') let index = arr.findIndex(item=>item.t); //查找每个元素中包含t的索引 arr.splice(index, 1); console.info('set-arr-empty', set, arr); //map-delete Set(0) {} [] } /* * Map 和 Array * */ { //数据结构横向对比 ,增删改查 let map = new Map(); let arr = []; //增 map.set('t', 1); arr.push({'t': 1}); console.info('map-array', map, arr); //查 let map_exist = map.has('t'); //boolean let array_exist = arr.find(item=>item.t); //如果存在 则返回数据的值 console.info('map-array', map_exist, array_exist); //map-array true {t: 1} //改 map.set('t', 2); arr.forEach(item=>item.t ? item.t = 2 : ''); console.info('map-modify', map, arr); //map-modify Map(1) {"t" => 2} [{t:2}] //删除 map.delete('t'); let index = arr.findIndex(item=>item.t); //查找每个元素中包含t的索引 arr.splice(index, 1); console.info('map-empty', map, arr); //map-delete Map(0) {} [] } /* * Map,Set,Object 的对比 * */ { let item = {'t': 1}; let map = new Map(); let set = new Set(); let obj = {}; //增 map.set('t', 1); set.add(item); obj['t'] = 1; console.info('map-set-obj', map, set, obj); //map-set-obj Map(1) {"t" => 1} Set(1) {{t:1}} {t: 1} //查 console.info({ map_exist: map.has('t'), set_exist: set.has(item), obj_exist: 't' in obj } //{map_exist: true, set_exist: true, obj_exist: true} ) //改 map.set('t',2); item.t=2; //set 保存引用地址 obj['t']=2; console.info('map-set-obj-modify', map, set, obj); //map-set-obj-modify Map(1) {"t" => 2} Set(1) {{…}} {t: 2} //删 map.delete('t'); set.delete(item); delete obj['t']; console.info('map-set-empty', map,set, arr); } /* * 对比小结: Map>Set>Array=Object * 1、在开发过程中涉及到的数据结构 能使用Map 不使用 Array 尤其是复杂的数据结构使用 * 2、如果对数据结构中的唯一性有要求 考虑使用Set 放弃使用Object做存储 * */