0Pricing
JavaScript Academy · 课时

众所周知的 Symbol

使用 Symbol.iterator 等 Symbol 自定义行为。

众所周知的 Symbol 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。

众所周知的符号

众所周知的符号是存储在 Symbol 对象上的内置符号。它们可以让您自定义对象在迭代和转换等语言功能中的行为。

console.log(typeof Symbol.iterator)
console.log(typeof Symbol.toPrimitive)

Symbol.iterator

Symbol.iterator 定义对象如何被 for-of 循环和展开运算符遍历。内置数组和字符串已经提供了它。

const arr = [10, 20]
const it = arr[Symbol.iterator]()
console.log(it.next().value)

让对象可迭代

您可以添加一个 Symbol.iterator 方法,让它返回带有 next 方法的迭代器,从而使任意对象都能用于 for-of 循环。

const range = {
  from: 1,
  to: 3,
  [Symbol.iterator]() {
    let cur = this.from
    const last = this.to
    return {
      next() {
        return cur <= last ? { value: cur++, done: false } : { value: undefined, done: true }
      }
    }
  }
}
for (const n of range) {
  console.log(n)
}

使用展开进行迭代

由于 Symbol.iterator 也负责展开操作,自定义可迭代对象可以被展开为数组。

const nums = {
  [Symbol.iterator]() {
    let i = 0
    return { next() { return i < 3 ? { value: i++, done: false } : { value: undefined, done: true } } }
  }
}
console.log([...nums])

Symbol.toPrimitive

Symbol.toPrimitive 允许对象控制自己在数值、字符串或默认上下文中如何转换为原始值。

const money = {
  amount: 50,
  [Symbol.toPrimitive](hint) {
    if (hint === "number") return this.amount
    return "$" + this.amount
  }
}
console.log(+money)
console.log(money + "")

提示参数

转换处理器会收到 number、string 或 default 之一的提示,使您能够针对每种情况返回合适的值。

const obj = {
  [Symbol.toPrimitive](hint) {
    return hint
  }
}
console.log(+obj)
console.log(obj + "")
console.log(String(obj))

Symbol.toStringTag

Symbol.toStringTag 可以自定义默认 toString 为对象报告的文本,适合用于自定义类型标签。

const widget = {
  [Symbol.toStringTag]: "Widget"
}
console.log(Object.prototype.toString.call(widget))

Symbol.hasInstance

Symbol.hasInstance 允许类或对象自定义 instanceof 运算符的行为。

class Even {
  static [Symbol.hasInstance](num) {
    return num % 2 === 0
  }
}
console.log(4 instanceof Even)
console.log(3 instanceof Even)

内置对象也会使用它们

数组、映射、集合和字符串都实现了 Symbol.iterator,因此它们可以顺畅地与 for-of 和展开操作配合使用。

const set = new Set([1, 2, 3])
console.log([...set])

它们为何重要

众所周知的符号是扩展点:它们可以让您的对象自然地融入内置语言操作,而不必为其编写特殊处理。

const list = {
  items: ["a", "b"],
  [Symbol.iterator]() {
    return this.items[Symbol.iterator]()
  }
}
for (const x of list) {
  console.log(x)
}

发现它们

Symbol 对象会将这些符号公开为静态属性。您可以在需要的地方像引用 Symbol.iterator 和 Symbol.toPrimitive 一样引用它们。

console.log(typeof Symbol.iterator)
console.log(typeof Symbol.toStringTag)
console.log(typeof Symbol.hasInstance)

快速检查

测试您对众所周知的符号的了解。

回顾

回顾:众所周知的符号可以自定义语言行为。

  • Symbol.iterator 驱动 for-of 和展开操作
  • Symbol.toPrimitive 通过提示控制转换
  • Symbol.toStringTag 为对象添加标签
  • Symbol.hasInstance 自定义 instanceof
const r = { [Symbol.iterator]() { let i = 0; return { next() { return i < 2 ? { value: i++, done: false } : { value: 0, done: true } } } } }
console.log([...r])

常见问题解答

「众所周知的 Symbol」课时是免费的吗?

是的 — 「众所周知的 Symbol」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。

「众所周知的 Symbol」这节课中我会学到什么?

使用 Symbol.iterator 等 Symbol 自定义行为。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 JavaScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「众所周知的 Symbol」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 JavaScript Academy 课中编写并运行代码吗?

能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 创建唯一 Symbol
  2. 将 Symbol 用作对象键
  3. 全局 Symbol 注册表
  4. 众所周知的 Symbol
← 返回 JavaScript Academy