好用的 JavaScript Symbol 类型

 

声明定义symbol的几种方式:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>

    <script>
        // let a = Symbol();
        // let b = Symbol();
        // console.log(a);
        // console.log(typeof a);
        // console.log(a == b);

        // Symbol可以加上描述
        // let a = Symbol('这是a');
        // console.log(a);
        // console.log(a.toString());
        // console.log(a.description);

        // Symbol() 和Symbol.for() 的区别
        // let a = Symbol('cyy');
        // let b = Symbol('cyy');
        // console.log(a == b);

        // Symbol.for是在全局存储一个变量,可以使用Symbol.keyFor来获取到描述
        // Symbol()没有,不能获取到描述
        // let a2 = Symbol.for('cyy');
        // let b2 = Symbol.for('cyy');
        // console.log(a2 == b2);

        // console.log(Symbol.keyFor(a2));
    </script>
</body>

</html>

 

使用Symbol解决字符串耦合问题:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <style>

    </style>
</head>

<body>

    <script>
        // 前面的cyy属性被后面的覆盖
        //   let grade = {
        //       cyy: {
        //           class: 'html',
        //           score: 99
        //       },
        //       cyy2: {
        //           class: 'css',
        //           score: 28
        //       },
        //       cyy: {
        //           class: 'html',
        //           score: 33
        //       },
        //   };
        //   console.log(grade);

        // let user1 = 'cyy1';
        // let user2 = 'cyy2';
        // let grade = {
        //     user1: {
        //         class: 'html',
        //         score: 99
        //     },
        //     user2: {
        //         class: 'css',
        //         score: 28
        //     },
        // };
        // console.log(grade);

        // 属性名需要加上中括号才能使用变量
        // let user1 = 'cyy1';
        // let user2 = 'cyy2';
        // let grade = {
        //     [user1]: {
        //         class: 'html',
        //         score: 99
        //     },
        //     [user2]: {
        //         class: 'css',
        //         score: 28
        //     },
        // };
        // console.log(grade);

        let user1 = {
            name: 'cyy1',
            key: Symbol()
        };
        let user2 = {
            name: 'cyy2',
            key: Symbol()
        };

        let grade = {
            [user1.key]: {
                class: 'html',
                score: 99
            },
            [user2.key]: {
                class: 'css',
                score: 28
            },
        };
        console.log(grade);
        console.log(grade[user1.key]);
        console.log(grade[user2.key]);
    </script>
</body>

</html>

 

 

Symbol在缓存容器中的使用:

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <style>

    </style>
</head>

<body>


    <script>
        class Cache {
            static data = {};
            static set(name, value) {
                return this.data[name] = value;
            }
            static get(name) {
                return this.data[name];
            }
        }
        // Cache.set('cyy', 'girl');
        // console.log(Cache.get('cyy'));

        // 存在覆盖的情况  
        // let user = {
        //     name: 'apple',
        //     desc: '用户'
        // };
        // let cart = {
        //     name: 'apple',
        //     desc: '购物车'
        // };
        // Cache.set('apple', user);
        // Cache.set('apple', cart);
        // console.log(Cache.get('apple'));

        // 传统解决方法
        // let user = {
        //     name: 'apple',
        //     desc: '用户'
        // };
        // let cart = {
        //     name: 'apple',
        //     desc: '购物车'
        // };
        // Cache.set('user-apple', user);
        // Cache.set('cart-apple', cart);
        // console.log(Cache.get('user-apple'));

        let user = {
            name: 'apple',
            desc: '用户',
            key: Symbol()
        };
        let cart = {
            name: 'apple',
            desc: '购物车',
            key: Symbol()
        };
        Cache.set(user.key, user);
        Cache.set(cart.key, cart);
        console.log(Cache.get(user.key));
    </script>
</body>

</html>

 

扩展特性与对象属性保护:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <style>

    </style>
</head>

<body>


    <script>
        // Symbol的对象属性保护,无法使用for-of或者for-in来循环遍历
        // let symbol = Symbol('这是一个symbol类型');
        // let obj = {
        //     name: 'cyy',
        //     [symbol]: 'cyy-symbol'
        // };
        // for (let o of obj) {
        //     console.log(o);
        // }
        // for (let k in obj) {
        //     console.log(k);
        // }
        // for (let k of Object.keys(obj)) {
        //     console.log(k);
        // }

        // 只遍历symbol属性
        // for (let k of Object.getOwnPropertySymbols(obj)) {
        //     console.log(k);
        // }

        // 遍历所有属性
        // for (let k of Reflect.ownKeys(obj)) {
        //     console.log(k);
        // }

        // 对象属性保护,不希望让外界获取到的属性
        let secret = Symbol('这是我的小秘密~');
        class User {
            // 构造函数
            constructor(name) {
                this.name = name;
                this[secret] = '保密';
            }
            getName() {
                return `${this.name}--${this[secret]}`;
            }
        }
        let c = new User('cyy呀');
        console.log(c.getName());
        for (let k in c) {
            console.log(k);
        }
    </script>
</body>

</html>

补充一下

Reflect.ownKeys()与Object.keys()区别

var obj = {
    a: 1,
    b: 2
}
Object.defineProperty(obj, 'method', {
    value: function () {
        alert("Non enumerable property")
    },
    enumerable: false
})

console.log(Object.keys(obj))
// ["a", "b"]
console.log(Reflect.ownKeys(obj))
// ["a", "b", "method"]

从结果上看出:

Object.keys()返回属性key,但不包括不可枚举的属性
Reflect.ownKeys()返回所有属性key

Object.keys() : 相当于返回属性数组

Reflect.ownKeys() :相当于Object.getOwnPropertyNames(target) concat(Object.getOwnPropertySymbols(target)

getOwnPropertyNames():方法: 返回所有属性的数组

Object.getOwnPropertySymbols():方法: 返回所有符号属性直接发现在给定的对象

参考链接:https://blog.csdn.net/oxgos/article/details/82854848

posted @ 2020-11-16 22:05  陈莺莺呀  阅读(275)  评论(0编辑  收藏  举报