1

Symbol由来

Symbol是ES6引入的新类型,所以在ES5的基础上,JS就有了字符串(string)、数字型(number)、布尔(bool)、null、undefined和Symbol共六种基本类型(bigint ES2016 添加)。

In JavaScript, Symbol is a primitive value.
Symbol是一种原始数据类型
什么是原始数据类型
A value having the data type "symbol" can be referred to as a "symbol value." In the JavaScript run-time environment, a symbol value is created by invoking the function Symbol, which dynamically produces an anonymous, unique value. A symbol may be used as an object property.
具有Symbol数据类型的值被称为"Symbol"值。在JavaScript运行时环境中,通过调用函数Symbol创建Symbol值,该函数动态生成匿名唯一值。
Symbol can have an optional description, but for debugging purposes only.
MDN Symbol
该数据类型通常被用作一个对象属性的键值——当你想让它是私有的时候。例如,symbol 类型的键存在于各种内置的 JavaScript 对象中。同样,自定义类也可以这样创建私有成员。symbol 数据类型具有非常明确的目的,并且因为其功能性单一的优点而突出;一个 symbol 实例可以被赋值到一个左值变量,还可以通过标识符检查类型,这就是它的全部特性。不能对该类型实例使用其他操作符(将“Symbol”类型的实例与 “Number” 类型的实例对比,例如整数 42,该实例就具有将值与其他类型的值进行比较或组合的运算符)。

创建和使用Symbol

Symbol值的唯一创建方法,是通过调用Symbol()函数来返回,不支持new操作。
Symbol接受一个可选参数,可以添加一段文本描述,但这段描述不可用于属性访问。

let firstName = Symbol("first name");
let persion = {};
person[firstName] = "Tom";
console.log("first name" in person); // false
console.log(persion[firstName]); // "Tom"
console.log(firstName); // "Symbol(first name)"

Symbol的描述被存储在内部的[[Description]]属性中,只有当调用Symbol的toString方法才可以读取这个属性,但不能直接在代码里访问[[Description]]。
所有使用计算属性名的地方,都可以使用Symbol。

let firstName = Symbol("first name");

let person = {
    [firstName] : "Tom" 
}

Object.defineProperty(person, firstName, { writable: false});

let lastName = Symbol("last name");

Object.defineProperties(person, {
    [lastName]: {
        value: 'Lee',
        writable: false
    }
});

console.log(person[firstName]); // Tome
console.log(person[lastName]); // Lee

const propertyNames = Object.getOwnPropertyNames(person);
console.log(propertyNames); // []

const propertySymbols = Object.getOwnPropertySymbols(person);

console.log(propertySymbols); // [Symbol(first name), Symbol(last name)]

共享体系

Symbol提供了一个全局注册表,用于在大文件或多文件代码中追踪Symbol值。
如果想创建一个可共享的Symbol,需要使用Symbol.for方法。它只接受一个参数,也就是即将创建的Symbol的字符串标识,这个参数也被用作Symbol的描述。

let uid = Symbol.for("uid");
let obj = {};
obj[uid] = "12345";
console.log(obj[uid]); // "12345"
console.log(uid); // "Symbol(uid)"
console.log(Symbol.forKey(uid)); // "uid"

Symbol.for方法首先在全局注册表中搜索键值为"uid"的Symbo值,如果存在,直接返回已有的Symbol,否则,创建一个新的Symbol,并使用这个键在Symbol全局注册表中注册,随即返回新创建的Symbol。


anleo
30 声望1 粉丝

准备写es6系列、设计模式(node,javascript)、前端工程化、TDD&BDD(Reactjs&angularjs)