含义
symbol译为标识,在js中更准确的表示为独一无二的值。
使用
let a=Symbol();
通过上面的方法就可以创建一个简单的symbol对象。它还可以接收一个参数来对生成的symbol值进行描述,如下let a=Symbol("我是a");,注意到无论传的参数是否一致得到的symbol值都是不相同的,这也就是上面所说的独一无二的特性。
let a=Symbol("我是a");
let b= Symbol.for("我是a");
console.log(a===b);//false
借助上面这一特性,所以我们可以很好的引出下面的有应用场景。
应用场景介绍
一:消除魔术字符串:
什么是魔术字符串? 在编写项目的时候,我们难免会写出一些字符常量来,这时候如果出现很多的魔术字符串,就有可能造成冲突,特别是将项目交由下一个开发者的时候。
//在vue中我们有时候要通过事件总线传递事件的时候
1. 在main.js中挂载EventBus
2. 在A页面发送事件
3. 在B页面监听事件
1.// main.js文件中 // 通过new Vue 来创建EventBus对象,然后将其挂载到全局
Vue.prototype.$Bus = new Vue();
2.// A 组件 文件中 // 通过 this.$Bus.$emit 来发送事件
this.$Bus.$emit('busClick','我是来自A页面的信息');
3.// B 组件 文件中 // 通过 this.$Bus.$on 来监听EvenBus事件
// 需要注意,需要在vue中生命周期中监听,如在 created 中监听
created() {
this.$Bus.$on(
'busClick',(res)=>{ console.log(res,'监听到了');
})
}
在上面的例子中busClick就是所谓的魔术字符串,在开发中我们可以创建instance.js文件来进行统一存放,然后在需要用到的地方进行引入即可
//instance.js
let BUSCLICK="busClick";
//es6有了symbol后
let BUSCLICK=Symbol("busClick");
优点就是在多人操作同一个instance.js文件的时候,我们不必要担心自己的事件名称会和别人造成重复从而造成冲突(其实只要是在程序中用到的字符串【次数大于2】就可以考虑使用symbol来避免使用不一致和声明重复的问题)。
防止对象的属性名被覆盖
let name=Symbol("姓名");
let person={
[name]:"张三"
}
console.log(person[name]);//张三
注意到上面的例子中,给对象添加属性的key值时候,要用【】因为平时写的时候其实是语法糖,如果直接写nane会被当成字符串“name”,而不是symbol-name了,在读取的时候同理。
模拟类的私有方法
利用 symbol 不会被常规的方法(除了 Object.getOwnPropertySymbols 外)遍历到,所以可以用来模拟私有变量。
let name=Symbol("姓名")
let person={
[name]:"zhangsan",
age:18,
height:1.88
}
for (const key in person) {
console.log(person[key]);//1.8 1.88
}
其他知识点
一:可以注意到在symbol前面是没有new关键字的。这是为什么呢?
注意到通过 new 实例化的结果是一个 object 对象,而不是原始类型的 symbol,这就涉及到new时候发生了什么?
1.内部创建一个新的对象。
2.将对象原型链上的东西与对象进行链接,因为对象可以访问到原型链上的的属性。
3.该对象可以访问到构造函数中this上的任意属性。
4.如果返回值是一个对象就返回改对象,否则返回新创建的这个对象。
二:Symbol.for
改方法可以检测上下文中是否已经存在使用该方法且相同参数创建的 symbol 值,如果存在则返回已经存在的值,如果不存在则新建。
const s1 = Symbol.for('foo');
const s2 = Symbol.for('foo');
console.log(s1 === s2); // true