为什么要通过括号访问 Symbol.iterator?
Why do you access Symbol.iterator via brackets?
如果我创建一个数组,例如,var array=[1,2,3,4];
到 return 一个迭代器,我会做 var iterator = array[Symbol.iterator]();
我不明白你为什么访问 Symbol.iterator 属性 通过括号?为什么不只是 array.Symbol.iterator
?
在名为 Symbol
的数组上没有 属性(除非你把一个放在那里)。相反,您正在查找其键是 Symbol.iterator
指向的符号基元的值。 Symbol.iterator
returns 一个符号,您使用该符号作为查找键。这有点像用变量查找 属性:
let a = [1, 2, 3]
a.someProp = "hello"
let key = "someProp"
// this doesn't work for the same reason s.Symbol.iterator doesn't:
// a.key
// but this does:
console.log(a[key])
// So with a Symbol:
let k = Symbol.iterator
console.log(typeof k)
// k is now a reference to the symbol that is the key
// you can use that to returns the iterator function
console.log(a[k]) // <-- that returns your iterator function
console.log([...a[k]()])
// equivalent to:
console.log([...a[Symbol.iterator]()])
array.Symbol.iterator
表示 "access the Symbol
member of the array
variable, and then access that value's iterator
member" 但是这将 return 错误 Uncaught TypeError: Cannot read property 'iterator' of undefined
因为数组没有名为 Symbol
的成员所以它 returns undefined
和 undefined
没有 iterator
成员。
JS中的点.
运算符是左结合的,所以它是从左到右求值的。您需要使用括号来阐明您想要什么,而您想要的是访问 Symbol
的 iterator
然后使用该值访问 array
变量的成员。
打个数学比方,array.Symbol.iterator
和array[Symbol.iterator]
的区别就像6 / 0 + 2
(未定义,不能被0除)和[=26=的区别](= 3,有效操作!)。
因为可迭代协议就是这样工作的。见 MDN:
The iterable protocol allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a for..of construct. Some built-in types are built-in iterables with a default iteration behavior, such as Array or Map, while other types (such as Object) are not.
In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a @@iterator key which is available via constant Symbol.iterator:
解释器需要一种方法来确定 generic 对象是否可迭代。虽然可以指定每个可迭代对象都有一个字符串 iterator
属性 ,当调用时, returns 该对象的迭代器,这可能是(预迭代器)的问题可能碰巧具有 iterator
属性 但不符合实际规范迭代器协议的对象。
要求通过(唯一的,特定于迭代器的)访问迭代器 属性 Symbol
确保不会发生此类有问题的冲突。
(作为旁注:array.Symbol.iterator
要求 Symbol
是 array
的 属性,这没有多大意义 - Symbol
是一个 全局对象 )
如果我创建一个数组,例如,var array=[1,2,3,4];
到 return 一个迭代器,我会做 var iterator = array[Symbol.iterator]();
我不明白你为什么访问 Symbol.iterator 属性 通过括号?为什么不只是 array.Symbol.iterator
?
在名为 Symbol
的数组上没有 属性(除非你把一个放在那里)。相反,您正在查找其键是 Symbol.iterator
指向的符号基元的值。 Symbol.iterator
returns 一个符号,您使用该符号作为查找键。这有点像用变量查找 属性:
let a = [1, 2, 3]
a.someProp = "hello"
let key = "someProp"
// this doesn't work for the same reason s.Symbol.iterator doesn't:
// a.key
// but this does:
console.log(a[key])
// So with a Symbol:
let k = Symbol.iterator
console.log(typeof k)
// k is now a reference to the symbol that is the key
// you can use that to returns the iterator function
console.log(a[k]) // <-- that returns your iterator function
console.log([...a[k]()])
// equivalent to:
console.log([...a[Symbol.iterator]()])
array.Symbol.iterator
表示 "access the Symbol
member of the array
variable, and then access that value's iterator
member" 但是这将 return 错误 Uncaught TypeError: Cannot read property 'iterator' of undefined
因为数组没有名为 Symbol
的成员所以它 returns undefined
和 undefined
没有 iterator
成员。
JS中的点.
运算符是左结合的,所以它是从左到右求值的。您需要使用括号来阐明您想要什么,而您想要的是访问 Symbol
的 iterator
然后使用该值访问 array
变量的成员。
打个数学比方,array.Symbol.iterator
和array[Symbol.iterator]
的区别就像6 / 0 + 2
(未定义,不能被0除)和[=26=的区别](= 3,有效操作!)。
因为可迭代协议就是这样工作的。见 MDN:
The iterable protocol allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a for..of construct. Some built-in types are built-in iterables with a default iteration behavior, such as Array or Map, while other types (such as Object) are not.
In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a @@iterator key which is available via constant Symbol.iterator:
解释器需要一种方法来确定 generic 对象是否可迭代。虽然可以指定每个可迭代对象都有一个字符串 iterator
属性 ,当调用时, returns 该对象的迭代器,这可能是(预迭代器)的问题可能碰巧具有 iterator
属性 但不符合实际规范迭代器协议的对象。
要求通过(唯一的,特定于迭代器的)访问迭代器 属性 Symbol
确保不会发生此类有问题的冲突。
(作为旁注:array.Symbol.iterator
要求 Symbol
是 array
的 属性,这没有多大意义 - Symbol
是一个 全局对象 )