Skip to main content

JS 内置对象之 Symbol

  • symbol 是一种基本数据类型,一个 symbol 值能作为对象属性的标识符,这是该数据类型仅有的目的。
  • Symbol() 函数会返回唯一的 symbol 值。
  • 不支持语法 new Symbol()。

一、属性

1、search

Symbol.search 指定了一个搜索方法,这个方法接受用户输入的正则表达式,返回该正则表达式在字符串中匹配到的下标。

class caseInsensitiveSearch {
constructor(value) {
this.value = value.toLowerCase();
}
[Symbol.search](string) {
return string.toLowerCase().indexOf(this.value);
}
}

console.log('foobar'.search(new caseInsensitiveSearch('BaR'))); // 3

2、match

指定了匹配的是正则表达式而不是字符串。

const regexp1 = /foo/;
regexp1[Symbol.match] = false;

console.log('/foo/'.startsWith(regexp1)); // true

3、replace

指定了当一个字符串替换所匹配字符串时所调用的方法。

class Replace1 {
constructor(value) {
this.value = value;
}
[Symbol.replace](string) {
return `s/${string}/${this.value}/g`;
}
}

console.log('foo'.replace(new Replace1('bar'))); // "s/foo/bar/g"

4、toStringTag

作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签,通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里。

class ValidatorClass1 {}
Object.prototype.toString.call(new ValidatorClass1()); // "[object Object]"

class ValidatorClass2 {
get [Symbol.toStringTag]() {
return "Validator";
}
}
Object.prototype.toString.call(new ValidatorClass2()); // "[object Validator]"

二、方法

1、for

Symbol.for(key)

功能:据给定的键 key,来从运行时的 symbol 注册表中找到对应的 symbol,如果找到了则返回它,否则新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。

参数:key(必须):作为 symbol 注册表中与某 symbol 关联的键。

返回值:返回由给定的 key 找到的 symbol,否则就是返回新创建的 symbol。

示例:

Symbol.for("foo"); // 创建一个 symbol 并放入 symbol 注册表中,键为 "foo"
Symbol.for("foo"); // 从 symbol 注册表中读取键为"foo"的 symbol

console.log(Symbol.for("bar") === Symbol.for("bar")); // true,证明了上面说的
console.log(Symbol("bar") === Symbol("bar")); // false,Symbol() 函数每次都会返回新的一个 symbol

2、keyFor

Symbol.keyFor(sym)

功能:用来获取全局symbol 注册表中与某个 symbol 关联的键。

参数:sym(必选):需要查找键值的某个 Symbol。

返回值:如果全局注册表中查找到该 symbol,则返回该 symbol 的 key 值,返回值为字符串类型。否则返回 undefined。

示例:

// 创建一个全局 Symbol
var globalSym = Symbol.for("foo");
Symbol.keyFor(globalSym); // "foo"

var localSym = Symbol();
Symbol.keyFor(localSym); // undefined,

// 以下Symbol不是保存在全局Symbol注册表中
Symbol.keyFor(Symbol.iterator) // undefined

3、toString

symbol.toString()

功能:将 symbol 对象转字符串。

参数:

返回值:返回当前 symbol 对象的字符串表示。

示例:

// 创建一个全局 Symbol
Symbol("desc").toString(); // "Symbol(desc)"

// well-known symbols
Symbol.iterator.toString(); // "Symbol(Symbol.iterator)

// global symbols
Symbol.for("foo").toString() // "Symbol(foo)"

4、valueOf

symbol.valueOf()

功能:将 symbol 对象中包含的 symbol 转原始值。

参数:

返回值:返回当前 symbol 对象所包含的 symbol 原始值。

示例:

Object(Symbol("foo")) + "bar";
// TypeError: can't convert symbol object to primitive
// 无法隐式的调用 valueOf() 方法

Object(Symbol("foo")).valueOf() + "bar";
// TypeError: can't convert symbol to string
// 手动调用 valueOf() 方法,虽然转换成了原始值,但 symbol 原始值不能转换为字符串

Object(Symbol("foo")).toString() + "bar";
// "Symbol(foo)bar",需要手动调用 toString() 方法才行