在 ES6 (ECMAScript 2015)中,加入了一个全新的数据类型——Symbol(符号)。Symbol 不同于之前的数据类型,它是一种类似于字符串的原始数据类型,唯一的区别是 Symbol 类型的值是唯一、不可变的。在本文中,我们将讨论什么是 Symbol 对象,为什么要使用它,以及如何使用它。
1. Symbol 对象的定义和特点
Symbol 对象是ES6 中的一个新的数据类型。和其他数据类型不同的是,Symbol 值是唯一的,不可改变的。Symbol 对象可以通过 Symbol() 函数进行创建,并且可以传入一个字符串参数,用于表示每个 Symbol 实例的描述性标记。
let s1 = Symbol(); let s2 = Symbol("description");
s1 和 s2 都是 Symbol 实例,s2 的描述性标记为 "description"。
2. Symbol 对象的应用场景
2.1. 属性名的唯一性
在前端应用中,我们会经常使用对象来存储数据。由于在 JavaScript 中对象的属性名必须是字符串,所以如果我们创建的两个对象有相同的属性名时,后一个属性会覆盖前一个属性值。这时候,Symbol 对象就可以很好地解决这个问题了。
// javascriptcn.com 代码示例 const obj = { }; const key1 = Symbol("key1"); const key2 = Symbol("key2"); obj[key1] = "value1"; obj[key2] = "value2"; console.log(obj[key1]); // "value1" console.log(obj[key2]); // "value2"
上述代码中,我们创建了两个 Symbol 对象,使用它们作为属性名,就可以保证属性名的唯一性。
2.2. 遍历对象属性
Symbol 所代表的属性在使用 for .. in 遍历时不会出现。这个特性可以在对象中定义一些不想暴露的属性,同时确立对象枚举属性的边界,提高了程序的健壮性。
// javascriptcn.com 代码示例 const obj = { }; const key1 = Symbol("key1"); const key2 = Symbol("key2"); obj[key1] = "value1"; obj[key2] = "value2"; obj.a = "valueA"; obj.b = "valueB"; for (let key in obj) { console.log(key + ": " + obj[key]); }
输出结果:
a: valueA b: valueB
可以看出,使用 for .. in 遍历 obj 时,只遍历了 a 和 b 两个用字符串定义的属性,而没有遍历使用 Symbol 定义的 key1 和 key2 属性。
2.3. 使用 Symbol 定义对象常量
常量在 JavaScript 中很难被定义和实现。ES6 中,使用 Symbol 可以实现常量的定义。
const actions = { ADD : Symbol(), EDIT : Symbol(), DELETE : Symbol() };
上述代码中,我们使用 Symbol 对象创建了一个常量对象,其中 ADD、EDIT 和 DELETE 三个常量属性都是通过 Symbol 对象创建的。这样可以确保常量的唯一性,避免了其他属性或字符串常量的可能混淆。
3. Symbol 对象的方法
3.1. Symbol.for() 和 Symbol.keyFor()
Symbol.for() 用于搜索具有给定名称的 Symbol。如果找到,则返回该 Symbol 对象,否则会创建一个新的 Symbol。
const key1 = Symbol.for("key"); const key2 = Symbol.for("key"); console.log(key1 === key2); // true
Symbol.for() 创建具有给定名称的 Symbol,如果已经存在该名称的 Symbol,则返回该 Symbol。这意味着 key1 和 key2 实际上是同一个 Symbol。
而 Symbol.keyFor() 则返回一个已经使用 Symbol.for() 创建的 Symbol 对象的注册名称。
const key1 = Symbol.for("key"); console.log(Symbol.keyFor(key1)); // "key"
上述代码中,我们使用了 Symbol.for() 方法创建了一个 Symbol 对象 key1,并且将其注册名记录为 "key"。我们再使用 Symbol.keyFor() 方法来获取该注册名。
3.2. Symbol.hasInstance
Symbol.hasInstance 是一个内置的 Symbol,它是一个方法,用于判断对象是否为某个构造函数的实例。
class Person { } const p = new Person(); console.log(p instanceof Person); // true console.log(Person[Symbol.hasInstance](p));// true
上述代码中,我们先使用 instanceof 操作符判断对象 p 是否是构造函数 Person 的实例。然后,在构造函数 Person 的 Symbol.hasInstance 方法中进行同样的判断,返回的结果相同。
4. 总结
在 ES6 中,Symbol 对象作为新的数据类型有其独特的特点,可以解决属性名的唯一性、使对象属性枚举更加精准、定义常量等应用场景。同时,Symbol 对象的内置方法还可以用于判断对象是否为某个构造函数的实例等操作,Symbol 很好地解决了 JavaScript 属性名的重复问题,可以方便地扩展开发者的代码功能。同时,注意 Symbol 对象创建后不可变性的特点,使用 Symbol 时要注意保证对象属性的一致性,防止 Symbol 重复引发的问题。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653cf3e37d4982a6eb6e1b89