TypeScript中Symbol.iterator为何要使用方括号定义?
为什么定义迭代器时要在
Symbol.iterator外加方括号 这里的方括号本质是JavaScript/TypeScript通用的计算属性名语法,和迭代器本身没有特殊绑定。
省略方括号会发生什么
普通对象的方法定义,如果方法名是合法的JS标识符,可以直接简化写法,不需要额外包裹:
// 两种写法完全等价 const user = { getName() {}, "getAge": function() {} }
但如果你直接写*Symbol.iterator() {}、省略方括号,引擎会把这个方法的名称直接解析成固定的字符串"Symbol.iterator",最终生成的对象属性键是字符串类型,不是我们需要的Symbol类型键。
这会直接违背JS的迭代协议要求——协议明确规定,可迭代对象的迭代器入口,必须挂载在Symbol.iterator这个全局符号值对应的属性键上,挂在字符串键上的方法完全不会被内置的可迭代特性识别。
方括号的实际作用
在对象字面量的属性名位置加方括号,是引擎规定的固定规则:方括号内的内容不会被当成固定字符串,而是会先被求值,求值的真实结果会被当作对象的属性键。
对应到你的迭代器定义场景,[Symbol.iterator]的执行逻辑是:
- 先取全局的
Symbol.iterator符号常量的真实值 - 把这个符号值作为当前生成器方法的挂载键
- 让这个对象满足可迭代协议的要求,可以被
for...of循环、展开运算符、数组解构等特性正常识别
你可以做个简单验证:去掉方括号重新编译这段代码,再尝试对
numbers做for (const n of numbers)遍历,TS和JS都会抛出「object is not iterable」的报错。
内容的提问来源于stack exchange,提问作者Johannes Schacht
相关产品推荐
相关产品推荐

