symbol初学

symbol理解

  • symbol 是一种基本数据类型 (primitive data type)。
  • Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。
  • 静态属性暴露几个内建的成员对象
  • 静态方法会暴露全局的symbol注册,且类似于内建对象类
  • 作为构造函数来说它并不完整,因为它不支持语法:“new Symbol()”。
var sym = new Symbol(); // TypeError
  • 每个从Symbol()返回的symbol值都是唯一
  • 目的:symbol值能作为对象属性的标识符
const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol('foo');

console.log(typeof symbol1);
// expected output: "symbol"

console.log(symbol2 === 42);
// expected output: false

console.log(symbol3.toString());
// expected output: "Symbol(foo)"

console.log(Symbol('foo') === Symbol('foo'));
// expected output: false

语法

  • Symbol([description])
  • 参数 :description 可选的,字符串类型。对symbol的描述,可用于调试但不是访问symbol本身
  • Symbol(“foo”) 不会强制将字符串 “foo” 转换成symbol类型。它每次都会创建一个新的 symbol类型:

Symbol 包装器对象 (Symbol wrapper object)

var sym = Symbol("foo");
typeof sym;     // "symbol"
var symObj = Object(sym);
typeof symObj;  // "object"

创建全局共享的 Symbol

  • 上面使用Symbol() 函数的语法,不会在你的整个代码库中创建一个可用的全局的symbol类型。 要创建跨文件可用的symbol,甚至跨域(每个都有它自己的全局作用域) ,
  • 使用 Symbol.for() 方法 和Symbol.keyFor() 方法从全局的symbol注册表设置和取得symbol。

Symbol.for()

  • Symbol.for(key) 方法会根据给定的键 key,来从运行时的 symbol 注册表中找到对应的 symbol
  • key是用来标识每一个symbol
  • 如果找到了,则返回
  • 否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。
Symbol.for("foo"); // 创建一个 symbol 并放入 symbol 注册表中,键为 "foo"
Symbol.for("foo"); // 从 symbol 注册表中读取键为"foo"的 symbol

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

var sym = Symbol.for("mario");
sym.toString();
// "Symbol(mario)",mario 既是该 symbol 在 symbol 注册表中的键名,又是该 symbol 自身的描述字符串

//为了防止冲突,最好给你要放入 symbol 注册表中的 symbol 带上键前缀。
Symbol.for("mdn.foo");
Symbol.for("mdn.bar");
  • Symbols 在 for…in 迭代中不可枚举。另外,
  • Object.getOwnPropertyNames() 不会返回 symbol 对象的属性,
  • 但是你能使用 Object.getOwnPropertySymbols() 得到它们。
var obj = {};

obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";

// [Symbol("a")]和[Symbol.for("b")] 为symbols 所以不能输出
for (var i in obj) {
   console.log(i); // logs "c" and "d"
}

Symbol.keyFor()

  • Symbol.keyFor(sym):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

在对象中查找 Symbol 属性

Object.getOwnPropertySymbols() 方法

  • 在查找一个给定对象的符号属性时返回一个symbol类型的数组
  • 每个初始化的对象都是没有自己的symbol属性的,因此这个数组可能为空,除非你已经在对象上设置了symbol属性。

属性

  • Symbol.length:长度属性,值为0。
  • Symbol.prototype:symbol构造函数的原型。

迭代symbols

Symbol.iterator

  • 一个返回一个对象默认迭代器的方法。被 for…of 使用。
const iterable = {
  [Symbol.iterator]() {
    return {
      i: 0,
      next() {
        if (this.i < 3) {
          return { value: this.i++, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};
for (const value of iterable) {
  console.log(value);
}
// 0
// 1
// 2

自定义迭代器

var myIterable = {}
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};
[...myIterable] // [1, 2, 3]

Symbol.asyncIterator

  • 一个返回对象默认的异步迭代器的方法。被 for await of 使用。

正则表达式 symbols

Symbol.match

  • 一个用于对字符串进行匹配的方法,也用于确定一个对象是否可以作为正则表达式使用。被 String.prototype.match() 使用。

Symbol.replace

  • 一个替换匹配字符串的子串的方法. 被 String.prototype.replace() 使用。

Symbol.search

Symbol.split

其他 symbols

Symbol.hasInstance
一个确定一个构造器对象识别的对象是否为它的实例的方法。被 instanceof 使用。
Symbol.isConcatSpreadable
一个布尔值,表明一个对象是否应该flattened为它的数组元素。被 Array.prototype.concat() 使用。
Symbol.unscopables
拥有和继承属性名的一个对象的值被排除在与环境绑定的相关对象外。
Symbol.species
一个用于创建派生对象的构造器函数。
Symbol.toPrimitive
一个将对象转化为基本数据类型的方法。
Symbol.toStringTag
用于对象的默认描述的字符串值。被 Object.prototype.toString() 使用。

方法

Symbol.for(key)

  • 使用给定的key搜索现有的symbol,如果找到则返回该symbol。否则将使用给定的key在全局symbol注册表中创建一个新的symbol

Symbol.keyFor(sym)

  • 从全局symbol注册表中,为给定的symbol**检索一个共享的?**symbol key。

Symbol 原型

所有 Symbols 继承自 Symbol.prototype (en-US).

实例属性

Symbol.prototype.description
一个只读的字符串,意为对该 Symbol 对象的描述

实例方法

Symbol.prototype.toSource
返回该 Symbol 对象的源代码。该方法重写了 Object.prototype.toSource 方法
Symbol.prototype.toString
返回一个包含着该 Symbol 对象描述的字符串。该方法重写了 Object.prototype.toString 方法
Symbol.prototype.valueOf
返回该 Symbol 对象。该方法重写了 Symbol.prototype.valueOf 方法
Symbol.prototype[@@toPrimitive]
返回该 Symbol 对象。

Symbol 类型转换

当使用 symbol 值进行类型转换时需要注意一些事情:

  • 尝试将一个 symbol 值转换为一个 number 值时,会抛出一个 TypeError 错误 (e.g. +sym or sym | 0).
  • 使用宽松相等时, Object(sym) == sym returns true.
  • 这会阻止你从一个 symbol 值隐式地创建一个新的 string 类型的属性名。例如,Symbol(“foo”) + “bar” 将抛出一个 TypeError (can’t convert symbol to string).
  • “safer” String(sym) conversion 的作用会像symbol类型调用 Symbol.prototype.toString() 一样,但是注意 new String(sym) 将抛出异常。

详情看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值