在 ES6 中,Symbol 是一种新的数据类型。它是一种非字符串的、唯一的标识符,用于防止属性名的冲突。
Symbol 的创建
Symbol 对象的创建非常简单,只需要使用全局的 Symbol 函数即可。Symbol 函数可以接受一个字符串作为参数,用于描述该 Symbol 对象。
let sym1 = Symbol(); let sym2 = Symbol('foo'); let sym3 = Symbol('foo'); console.log(sym1 === sym2); //false console.log(sym2 === sym3); //false
以上代码中,sym2 和 sym3 都有相同的描述,但它们依然是不同的,这意味着 Symbol 是一种唯一的标识符。
Symbol 作为对象属性名
由于 Symbol 的唯一性,它可以被用作对象属性名,用以防止属性名的冲突。在对象字面量中要使用方括号来使用 Symbol 作为属性名。
let mySymbol = Symbol(); let obj = {}; obj[mySymbol] = 'Hello!'; console.log(obj[mySymbol]);
以上代码中,mySymbol 被用作 obj 对象的一个属性名,确保了该属性名不会和其他的属性名冲突。
Symbol 的内置属性
ES6 的内置对象有多个属性使用了 Symbol,以下是一些例子:
Symbol.iterator
Symbol.iterator 用于定义对象的默认迭代器方法。可以通过在对象的 Symbol.iterator 属性上指定符合条件的函数来实现自定义迭代器。
-- -------------------- ---- ------- --- ---------- - --- --------------------------- - --------- -- - ----- -- ----- -- ----- -- -- --- ---- ----- -- ----------- - ------------------- -
以上代码中,myIterable 对象实现了 Symbol.iterator 方法,该方法返回一个可以生成迭代值的迭代器。
Symbol.species
Symbol.species 属性用于指定衍生对象的构造函数,用于不同的对象派生出不同的新对象。
class MyArray extends Array { static get [Symbol.species]() { return Array; } } let a = new MyArray(1, 2, 3); let b = a.filter(x => x > 1); console.log(b instanceof MyArray); //false console.log(b instanceof Array); //true
以上代码中,在 MyArray 类中,[Symbol.species] 被设置为 Array,以确保当 MyArray 实例调用 filter 方法后返回的是一个 Array 实例。
总结
Symbol 是一种非常实用的数据类型,它可以确保属性名的唯一性,避免了对象属性名的冲突。还可以被用作 ES6 内置属性中的标识符。当我们需要防止属性名冲突或指定对象的默认迭代器方法和衍生对象的构造函数时,可以考虑使用 Symbol。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/648147b948841e98940b6e14