• ES6提供的 Set 【WeakSet】 和 Map 【WeakMap】 数据结构


    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>ES6提供的 Set 【WeakSet】 和 Map 【WeakMap】 数据结构</title>
        </head>
        <body>
            <script type="text/javascript">
                /*
                    基本类型: String、Number、Boolean、Null、Undefined、Symbol  【typeof 检测基本类型】
                    引用类型:对象(Object)、数组(Array)、函数(Function)
                */
                // js基本数据类型
                let a = undefined
                console.log(typeof a) // undefined
                let b = null
                console.log(typeof b) // object
                let c = 1
                console.log(typeof c) // number
                let d = true
                console.log(typeof d) // boolean
                let e = 'abc'
                console.log(typeof e) // string
                // 可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数BigInt()
                // BigInt 是一种内置对象,它提供了一种方法来表示大于 2^53 - 1 的整数。这原本是 Javascript中可以用 Number 表示的最大数字
                // BigInt 可以表示任意大的整数
                // BigInt 和 Number 不是严格相等的,但是宽松相等的
                const f = 10n;
                console.log(f, typeof f) // 10n "bigint"
                const g = BigInt(10)
                console.log(g, typeof g) // 10n "bigint"
                console.log(0n === 0) // false
                console.log(0n == 0) // true
                // 每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的
                const sy = Symbol();
                const sy1 = Symbol(42);
                console.log(typeof sy, sy1) // symbol  Symbol(42)
                console.log(Symbol(1) === Symbol(1)) // false
                
                // 引用数据类型
                let obj = new Object // 等价 new Object() 无参数()可省略
                console.log(obj, obj instanceof Object) // {} true
                // Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
                console.log(Object.create({}))
                let arr = new Array
                console.log(arr, arr instanceof Object, typeof arr) // [] true  object
                
                // 用 Object.create实现类式继承
                // ParentClass - 父类(superclass)
                function ParentClass() {
                  this.x = 0;
                  this.y = 0;
                }
                // 父类的方法
                ParentClass.prototype.move = function(x, y) {
                  this.x += x;
                  this.y += y;
                  console.info('ParentClass is change.');
                };
                // ChildClass - 子类(subclass)
                function ChildClass() {
                  ParentClass.call(this); // call super constructor.
                }
                // 子类续承父类
                ChildClass.prototype = Object.create(ParentClass.prototype);
                ChildClass.prototype.constructor = ChildClass;
                let newObj = new ChildClass()
                console.log(newObj, newObj instanceof Object) // ChildClass {x: 0, y: 0} true
                console.log(newObj, newObj instanceof ParentClass) // ChildClass {x: 0, y: 0} true
                newObj.move(2,2) // ParentClass is change.
                
                let fn  = function(){
                    console.log(this)
                } 
                console.log(fn, fn instanceof Object, typeof fn) // f(){console.log(this)} true  function
                // constructor判断            
                console.log([] instanceof Array);//->true
                console.log(/^$/ instanceof RegExp);//->true
                console.log([] instanceof Object);//->true
                console.log([].constructor === Array);//->true
                console.log([].constructor === Object);//->false 我们的constructor可以避免instanceof检测的时候,用Object也是true的问题
                console.log({}.constructor === Object); // true
                /*
                Array.isArray() ECMAScript5将Array.isArray()正式引入JavaScript,目的就是准确地检测一个值是否为数组 IE8不支持
                两个或者多个typeof一起使用时,返回值一定是"string";
                检测的不管是数组还是正则都返回的是"object",所以typeof不能判断一个值是否为数组
                Object.prototype.toString.call(value)  判断某个对象值属于哪种内置类型
                */
               
                // 接下来谈下这个 ES6中的Set 和 Map 数据结构
                // Set 数据结构
                let mySet = new Set()
                console.log(mySet,typeof mySet)  // Set(0){} "object"
                mySet.add(1)
                mySet.add(2)
                mySet.add(2)
                mySet.add(3)
                console.log(mySet) // Set(3){1,2,3}
                let setTest = new Set([1,2,3,4,5,5,6,6])
                let setArr = [...setTest]
                console.log(setTest) // Set(3){1,2,3,4,5,6}
                console.log(setArr) // [1, 2, 3, 4, 5, 6]
                // 结论
                /*
                    Set 数据结构 类似于数组但是Set不会添加重复的值
                    Set 加入值的时候,不会发生类型转换
                    [...new Set(array)] 可以去除数组重复成员的方法
                    [...new Set('string')].join('') 可以去除字符串里面的重复字符
                    Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化
                    Array.from方法可以将 Set 结构转为数组 【Array.from是将类数组转为数组的一种方法】
                    将类数组转为数组的方法:
                        1、Array的slice方法 例如:let arr = Array.prototype.slice.call(arguments);
                        2、Array.from() 例如:let arr = Array.from(arguments); 只要有length属性的对象,都可以应用此方法转换成数组
                        3、扩展运算符... 例如:let arr = [...arguments];  这种数据结构必须有遍历器接口
                        4、jquery的$.makeArray() 例如:let arr = $.makeArray(arguments);
                        使用Array的slice方法,此方法如果不传参数的话会返回原数组的一个拷贝,因此可以用此方法转换类数组到数组
                        let arr = Array.prototype.slice.call(arguments);
                            // 等同于
                        let arr = [].slice.call(arguments)
                */
               
               // WeakSet 数据结构
               const myWeakSet = new WeakSet();
               // myWeakSet.add(1) // 报错 Invalid value used in weak set
               console.log(myWeakSet,typeof myWeakSet) // WeakSet {} "object"
               const arrs = [[1, 2], [3, 4]];
               const ws = new WeakSet(arrs);
               console.log(ws) // WeakSet {[1, 2], [3, 4]}
               // 结论
                /*
                    WeakSet 结构与 Set 类似,也是不重复的值的集合
                    WeakSet 的成员只能是对象,而不能是其他类型的值
                    WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,
                    如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存
                    WeakSet 没有size属性 ES6 规定 WeakSet 不可遍历
                */
               
               // Map 数据结构
               const mp = new Map();
               console.log(mp,typeof mp) // Map(0) {} "object"
               const items = [
                    ['name', '小明'],
                    ['age', 28]
                ]
               items.forEach(
                 ([key, value]) => mp.set(key, value)
               )
               console.log(mp) // Map(2) {"name" => "小明", "age" => 28}
               
               const map = new Map();
                   map.set(1, 'aaa').set(1, 'bbb')
                console.log(map,map.get(1)) // Map(1) {1 => "bbb"}   'bbb'
                const mapTest = new Map([
                  [1, 'one'],
                  [2, 'two'],
                  [3, 'three'],
                ])
                console.log([...mapTest.keys()]) // [1, 2, 3]
                console.log([...mapTest.values()]) // ['one', 'two', 'three']
                console.log([...mapTest.entries()]) // [[1,'one'], [2, 'two'], [3, 'three']]
                console.log([...mapTest]) // [[1,'one'], [2, 'two'], [3, 'three']]
               // 结论
               /*
                    对同一个键多次赋值,后面的值将覆盖前面的值
                    读取【get方法】一个未知的键,则返回undefined
                    只有对同一个对象的引用,Map 结构才将其视为同一个键
                    同样的值的两个实例,在 Map 结构中被视为两个键
                    Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键
                    Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。
                    如果你需要“键值对”的数据结构,Map 比 Object 更合适
                    任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构都可以当作Map构造函数的参数, Set和Map都可以用来生成新的 Map
                    Map 结构转为数组结构,比较快速的方法是使用扩展运算符(...)
               */
              
                // WeakMap 数据结构
                const wmp = new WeakMap();
                console.log(wmp, typeof wmp) // WeakMap {} "object"
                let key = {age: 1}
                console.log(wmp.set(key,20)) // WeakMap {{…} => 20}
                console.log(wmp.get(key)) // 20
                // 结论 【WeakMap与Map的区别有两点】
                /*
                    WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名
                    WeakMap的键名所指向的对象,不计入垃圾回收机制
                    如果你要往对象上添加数据,又不想干扰垃圾回收机制,就可以使用 WeakMap
                    WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。WeakMap结构有助于防止内存泄漏
                    WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用
                    WeakMap 的另一个用处是部署私有属性 class _xx开头的
                */
            </script>
        </body>
    </html>
  • 相关阅读:
    Redis哨兵模式 (sentinel) (主从复制,读写分离)
    字符串的全排列
    测试链接
    vue数组能触发视图更新的方法
    PyCharm Shortcuts of macOS
    Tweak SecureCRT for macOS
    rsyslogd 以及日志轮替 logrotate
    阿里云服务器常见操作
    sh 启动jar
    招募军队(最小生成树)
  • 原文地址:https://www.cnblogs.com/lhl66/p/14509893.html
Copyright © 2020-2023  润新知