ES6(六)符号与符号属性1

2020-05-19  本文已影响0人  蒋小花_4b6c

在 JS 已有的基本类型(字符串、数值、布尔类型、 null 与 undefined )

 ES6 引入 了一种新的基本类型:符号( Symbol )

1.创建符号值

2.使用符号值

3.共享符号值

创建符号值

符号没有字面量形式,这在 JS 的基本类型中是独一无二的,有别于布尔类型的 true 或数 值类型的42  等等。

你可以使用全局 Symbol 函数来创建一个符号值,

let firstName = Symbol();

let person = {};

person[firstName] = "Nicholas";

console.log(person[firstName]); // "Nicholas"

由于符号值是基本类型的值,因此调用 new Symbol() 将会抛出错误。

let firstName = Symbol("first name");

let person = {};

person[firstName] = "Nicholas";

console.log("first name" in person); // false

console.log(person[firstName]); // Nicholas

console.log(firstName); // Symbol(first name)

Symbol 函数还可以接受一个额外的参数用于描述符号值,该描述并不能用来访问对应属性,

但它能用于调试

let symbol = Symbol("test symbol");

console.log(typeof symbol); // symbol

由于符号是基本类型的值,因此你可以使用 typeof 运算符来判断一个变量是否为符号。

使用符号值

可以在任意能使用“需计算属性名”的场合使用符号

 Object.defineProperty()  或 Object.defineProperties()

let firstName = Symbol("first name");

// 使用一个需计算字面量属性

let person = {

    [firstName]: "Nicholas"

};

// 让该属性变为只读

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

let lastName = Symbol("last name");

Object.defineProperties(person, {

    [lastName]: {

        value: "Zakas",

        writable: false

    }

});

console.log(person[firstName]); // "Nicholas"

console.log(person[lastName]); // "Zakas"

这个例子首先使用对象的“需计算字面量属性”方式创建了一个符号类型的属性 firstName , 该属性使用 getOwnPropertyDescriptor 查看时显示为可枚举( enumerable: true ),但无 法用 for-in 循环遍历,也不会显示在 Object.keys() 的结果中。下一行代码将该属性设置为 只读。接下来,使用  Object.defineProperties() 方法创建了一个只读的符号类型属性lastName ,而此时再次使用了“需计算字面量属性”方式,并将其作为第二个调用参数的一部 分。

共享符号值

例如:假设在应用中需要在两个不同的对象 类型中使用同一个符号属性,用来表示一个唯一标识符。跨越文件或代码来追踪符号值是很 困难并且易错的,为此, ES6 提供了“全局符号注册表”供你在任意时间点进行访问

创建共享符号值,应使用 Symbol.for() 方法而不是Symbol()方法。 Symbol.for() 方法仅接受单个字符串类型的参数,作为目标符号值的标识符,同时此参数也会成为该符号 的描述信息。

let uid = Symbol.for("uid");

let object = {};

object[uid] = "12345";

console.log(object[uid]); // 12345

console.log(uid); //  Symbol(uid)

  Symbol.for() 方法首先会搜索全局符号注册表,看是否存在一个键值为 "uid" 的符号值。 若是,该方法会返回这个已存在的符号值;

否则,会创建一个新的符号值,并使用该键值将 其记录到全局符号注册表中,然后返回这个新的符号值。

这就意味着此后使用同一个键值去 调用Symbol.for() 方法都将会返回同一个符号值,

如下:

let uid = Symbol.for("uid");

let object = {

    [uid]: "12345"

};

console.log(object[uid]); // "12345"

console.log(uid); // "Symbol(uid)"

let uid2 = Symbol.for("uid");

console.log(uid === uid2);  // true

console.log(object[uid2]);  // "12345"

console.log(uid2);  // "Symbol(uid)"

另一个独特用法,你可以使用 Symbol.keyFor() 方法在全局符号注册表中根据符号值检索出对应的键值:

let uid = Symbol.for("uid");

console.log(Symbol.keyFor(uid)); // "uid"

let uid2 = Symbol.for("uid");

console.log(Symbol.keyFor(uid2));   // "uid"

let uid3 = Symbol("uid");

console.log(Symbol.keyFor(uid3));   // undefined

符号值 uid3 在全局符号注册表中并不存在,因此没有关联的键值, Symbol.keyFor()  方法只会返回 undefined

上一篇 下一篇

猜你喜欢

热点阅读