Symbol的简单理解
Symbol
1.Symbol 的意义
之前我们的对象属性的数据类型都是字符串,没有其他的了。所以会导致属性名重复,导致属性值被覆盖的情况。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法,在添加的操作就很容易覆盖了原有的方法。所以需要一个独一无二的数据类型来完成这个使命。所以Symbol出来主持大局了。
2.Symbol的介绍
-
唯一性
Symbol这个英文单词表示“唯一",它是Javascript的第七种数据类型(Number,String,Boolean,null,undefined,Object),表示它是唯一的。
创建一个Symbol类型不需要用new操作符,否则会报错,因为生成的Symbol是一个原始类型的值,不是对象。直接let s = Symbol();测试s就是Symbol类型了。怎么说他是唯一的呢?let s = Symbol(); let ss = Symbol(); console.log(s == ss); //false //或者 let s = Symbol('a'); let ss = Symbol('a'); console.log(s == ss);//结果是false通过以上的比较,我们对
Symbol的唯一性,有了一定的了解。也就是说当你创建了一个Symbol数据后,那么就是独一无二的存在了。 -
数据类型的修饰
有人会好奇Symbol('a')里面的参数a又是怎么回事呢?字符串a表示一种修饰,对你当前创建的Symbol类型的一种修饰,作为区分使用,否则当你创建多个Symbol数据时,容易混淆。let s = Symbol('a'); let ss = Symbol('a'); console.log(s == ss);//false -
与其他数据类型之间的转换
Symbol不能用四则运算进行操作,否则报错。它只能用显式的方式转为字符串和布尔值,即:String(Symbol()) / Boolean(Symbol()) -
作为对象的属性
- 作为对象的属性时,注意要用以下三种方式来书写:
// 1. 作为对象的属性 let hobby = Symbol("hobby"); let level = Symbol("level"); let sex = Symbol("sex"); let person = { name: "小米", age: 21, [hobby]: "游泳" //1.1 } person[level] = "A" // 1.2 // 1.3 Object.defineProperty(person,sex,{ value: "男" }) console.log(person.level); //undefined console.log(person[hobby]); //游泳- 对象属性的创建
以上说了对象属性的创建,但是我们要格外的注意,
Symbol作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、object.getOwnPropertyNames()、JSON.stringify()返回。所以我们可以用Object.getOwnPropertySymbols方法,获取指定对象的所有Symbol属性名。
看到这是不是感觉用Symbol类型创建的对象属性这么麻烦吗?如果一个对象里面有字符串的属性又有Symbol的属性,难不成要分来获取对象属性吗?答案是不用,那必须使用新的API方法:Reflect.ownKeys(),这个方法就可以返回对象所有的属性,也就是字符串属性和Symbol属性。所以这里要留意了。// 2.遍历迭代不出 以symbol命名的属性 console.log(Object.keys(person)); //(2) ["name", "age"] console.log(Object.getOwnPropertySymbols(person));//(3) [Symbol(hobby), Symbol(level), Symbol(sex)] console.log(Object.getOwnPropertyNames(person));// ["name", "age"] // 解决: console.log(Reflect.ownKeys(person));// (5) ["name", "age", Symbol(hobby), Symbol(level), Symbol(sex)] -
Symbol.for()和Symbol.keyFor()有时,我们希望重新使用同一个
Symbol值,以上我们都说了Symbol数据类型是唯一的,所有只用Symbo()方法创建的Symbol类型是无法实现的。所有我们可以用Symbol.for()这个方法来实现。let s1 = Symbol.for("foo"); let s2 = Symbol.for("foo"); console.log(s1 === s2); //true // 使用Symbol.for会在全局查找有没有和自己一样的存在,如果没有,就创建并在全局登记,如果在全局登记中有,则直接用已经登记创建过的。所以s1 === s2注意,这里的
Symbol.for()和Symbol()创建的都是Symbol类型,但是他们的创建机制有所不同,Symbol.for(a')的创建方式会在创建之前在全局中寻找,有没有用Symbol.for()的方式,并且key是'a'的字符串创建了Symbol类型(创建了就会在全局中登记),如果有则不重复创建,直接用已创建的(已登记的)。然而Symbol("a')的创建是不会去检索全局的,是直接创建一个新的Symbol类型。这也是用Symbol(a')创建的两个Symbol类型不相等的根本原因。
Symbol.keyFor()方法返回一个已登记的Symbol类型值的key。let s1 = Symbol.for("foo"); let s2 = Symbol.for("foo"); let s3 = Symbol("foo"); console.log(Symbol.keyFor(s1));// foo console.log(Symbol.keyFor(s2));// foo console.log(Symbol.keyFor(s3));// undefined // Symbol.keyFor返回一个已经登记的 Symbol类型的 key

浙公网安备 33010602011771号