好用的 JavaScript Symbol 类型

  • A+
所属分类:Web前端
摘要

 声明定义symbol的几种方式: 使用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>

好用的 JavaScript Symbol 类型

 

 

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