在 ES6 中,新增了一种原始数据类型 Symbol,它可以用来创建唯一的标识符,解决属性名冲突的问题。本文将详细介绍 Symbol 的使用方法,包括创建 Symbol、Symbol 的属性和方法、Symbol 与对象的关系等方面,并提供实际应用示例。
创建 Symbol
在 ES6 中,我们可以使用 Symbol 函数来创建一个 Symbol,其语法如下:
let s = Symbol(description);
其中,description 表示可选的描述符,用来标识这个 Symbol。可以使用 toString 方法查看 Symbol 的描述符,例如:
let s = Symbol('foo'); console.log(s.toString()); // 输出:"Symbol(foo)"
需要注意的是,Symbol 的描述符并不是 Symbol 值的名称,不能像其他类型的属性一样访问。如果想要访问 Symbol 值,需要使用 Symbol 对象,例如:
let s = Symbol('foo'); let obj = { [s]: 'bar' }; console.log(obj[s]); // 输出 "bar" console.log(obj.foo); // 输出 "undefined"
Symbol 的属性和方法
Symbol 类型有以下常用属性和方法:
Symbol.iterator
一个函数,返回该对象默认的迭代器。可以使用 for...of 循环来遍历一个对象,默认情况下会调用 Symbol.iterator 方法。
let arr = [1, 2, 3]; let iter = arr[Symbol.iterator](); for (let i of iter) { console.log(i); } // 输出 1 2 3
Symbol.hasInstance
一个函数,用来判断是否为某个构造函数的实例。
class MyClass { static [Symbol.hasInstance](obj) { return obj instanceof Array; } } console.log([] instanceof MyClass); // 输出 true console.log({} instanceof MyClass); // 输出 false
Symbol.isConcatSpreadable
一个布尔值,表示该对象在使用 Array.prototype.concat() 方法时是否展开。
let arr1 = [1, 2, 3]; let arr2 = [4, 5, 6]; console.log(arr1.concat(arr2)); // 输出 [1, 2, 3, 4, 5, 6] arr2[Symbol.isConcatSpreadable] = false; console.log(arr1.concat(arr2)); // 输出 [1, 2, 3, [4, 5, 6]]
Symbol.species
一个函数,用来创建派生对象的构造函数。
-- -------------------- ---- ------- ----- ------- ------- ----- - ------ --- ------------------ - ------ ------ - - --- --- - --- ---------- -- --- --- ----- - ------------ ----------------- ---------- --------- -- -- ----- ----------------- ---------- ------- -- -- ----
Symbol 与对象的关系
我们可以使用 Symbol 为对象添加新的属性,避免与已有属性命名冲突。
const name = Symbol('name'); const person = { [name]: 'Tom' }; console.log(person[name]); // 输出 "Tom"
除此之外,我们可以使用 Symbol 作为属性名,使得该属性不会被 for...in、Object.keys 和 JSON.stringify 等方法枚举。例如:
-- -------------------- ---- ------- ----- ------ - ----------------- ----- --- - - ----- ------ --------- ----- -------- -- ------- -- --- ---- --- -- ---- - ----------------- -- -- ------ - ------------------------------ -- -- -------- --------------------------------- -- -- ----------------
实际应用示例
我们可以使用 Symbol 来创建一个只读属性,例如:
-- -------------------- ---- ------- ----- -------- - ------------------- ----- --- - --- ------------- - ----- -------------------------- ------- - ---- ---------- - ------ --------------- - --- ---------------------- -- -- ---- -------- - ------ ---------------------- -- -- ----
另外,我们可以使用 Symbol 来创建一些方法,例如:
-- -------------------- ---- ------- ----- ----- - ---------------- ----- ------ - ------------------- - ----------- - ------- - --------- - ------ --------- - ---------- - ------ ----------- - -- - - ----- - - --- ----------- ------------------------ -- -- -------- -------------------------- -- -- --
使用 Symbol 还可以创建一个全局的命名空间,避免不同模块之间的变量名冲突:
const myModule = {}; myModule[Symbol('privateVar')] = 'This variable is private'; myModule.foo = function() { console.log(this[Symbol('privateVar')]); }; myModule.foo(); // 输出 "undefined"
总结
Symbol 是 ES6 中新增的一种原始数据类型,用来创建唯一的标识符,可以解决属性名冲突的问题。本文详细介绍了 Symbol 的创建方法、属性和方法,并提供了实际应用示例。在实际编程中,我们可以灵活运用 Symbol 来提高代码的可读性和健壮性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/652c094f7d4982a6ebde2581