zl程序教程

您现在的位置是:首页 >  后端

当前栏目

js的Symbol使用

JS symbol 使用
2023-09-11 14:19:18 时间

Symbol

1、Symbol使用方法

let s = Symbol();
console.log(s);

Symbol永远不会是一样

Symbol是一个永远不会出现相同的字符串。在我们声明同一个变量的时候,如果重复出现,那麽只会打印第一次声明的那个变量。

let a = Symbol();
let b = Symbol();
console.log(a == b); // false

不能往里面压属性

let a = Symbol();
a.name = "Symbol";
console.log(a.name); 

加上一个描述

toString()打印其字符串

description 打印出对Symbol的描述

let a = Symbol('Symbol学习');
console.log(a.description); 

2、Symbol另一种定义方法

使用该方法,Symbol会在内存中开辟一个内存记录,如果使用重复的变量,可以使用Symbol.for()来定义。Symbol.keyFor()可以获得对Symbol的描述。

let symbol = Symbol.for('Symbol.for学习');
let symbol1 = Symbol.for('Symbol.for学习');
console.log(symbol == symbol1); // true
console.log(Symbol.keyFor(symbol)); // 获得对Symbol的描述

使用Symbol.for定义的会在全局保存,而使用普通的Symbol来定义的不是在全局定义,我们读取不到。

let symbol = Symbol('Symbol学习');
let symbol1 = Symbol.for('Symbol.for学习');
console.log(Symbol.keyFor(symbol)); // 读取不到
console.log(Symbol.keyFor(symbol1)); // 可以读取到

3、Symbol的使用

通过对象的声明方式得到user1和user2两个,其两个key都通过Symbol来绑定,在grade中使用是,user1.key需要使用‘ [] ’ 进行包裹,否则会当作字符串处理,[user1,key]则表示拿到对应的变量。最后可以通过自己想找到的元素来完成调用。

let user1 = {
            name: '李四',
            key: Symbol()
        };
        let user2 = {
            name: '李四',
            key: Symbol()
        };
        let grade = {
            [user1.key]: {
                js: 100,
                css: 89
            },
            [user2.key]: {
                js: 66,
                css: 55
            }
        }
        console.log(grade[user1.key]);

4、Symbol在缓存容器中的使用

为了更好的使用这个Symbol,我们常常会把公共的东西放在一个容器里面共享。

  • 通过下面声明变量,然后指定某个元素内特定的值进行输出。
 let user = {
            name: "apple",
            dese: "用户资料",
        };
        let cart = {
            name: "apple",
            dese: "购物车",
        };
        Cache.set('user-apple', user);
        Cache.set('cart-apple', cart);
        console.log(Cache.get("cart-apple"));
  • 通过key绑定Symbol完成不重复的调用
 let user = {
            name: "apple",
            dese: "用户资料",
            key: Symbol('会员资料')
        };
        let cart = {
            name: "apple",
            dese: "购物车",
            key: Symbol('购物车资料')
        };
        Cache.set(user.key, cart);
        Cache.set(cart.key, cart);
        console.log(Cache.get(user.key));

拓展

在我们数据不能公布或者改元素作为私有属性可以使用Symbol,但使用Symbol以后,想调用该属性内的元素不能使用for in 、 for of来使用,若想获取到symbol里面的元素,只能使用getOwnPropertySymbols;若想得到该数组的常用变量和symbol的属性,可以使用Reflect.ownKeys得到。

 <script>
        let symbol = Symbol('这是一个Symbol类型');
        let a = {
            name: 'abc',
            // 认为它是私有属性,受保护
            [symbol]: 'abcdefg'
        };
        // Symbol不能使用for in来遍历
        // for (const key in a) {
        //     console.log(key); // name
        // }

        // Symbol也不能使用for of来遍历
        for (const key of Object.keys(a)) {
            console.log(key);
        }

        // 若想遍历Symbol的属性,我们可以使用 getOwnPropertySymbols, 该方法不能遍历普通类型
        for (const key of Object.getOwnPropertySymbols(a)) {
            console.log(key);
        }

        // Reflect.ownKeys 遍历所有的属性
        for (const key of Reflect.ownKeys(a)) {
            console.log(key);
        }

        let site = Symbol("这是Symbol");
        class User {
            constructor(name) {
                this.name = name;
                this[site] = "symbol"
            }
            getName() {
                return `${this[site]} ${[this.name]}`;
            }
        }
        let user1 = new User('李四');
        console.log(user1.getName()); // symbol 李四

        for (const key in user1) {
            console.log(key); // 只能看到name
        }
    </script>