例如,如果我创建了一个数组,var array=[1,2,3,4];
以返回一个迭代器,我会做var iterator=array[Symbol.iterator]();
我不明白为什么要通过方括号访问Symbol.iterator属性?为什么不只是array.Symbol.iterator?
答案 0 :(得分:2)
名为Symbol
的数组上没有属性(除非您在其中放置了一个属性)。取而代之的是,您查找的值是谁的关键是Symbol.iterator
所指向的符号原语。 Symbol.iterator
返回一个符号,您可以将该符号用作查找关键字。就像查找带有变量的属性一样:
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]()])
答案 1 :(得分:1)
# Start an empty list
variable_bands = []
for question in weekday_cents_questions:
try:
# Check if it is empty, otherwise you'll get an IndexError
if variable_bands == []:
q = question.format(0)
else:
q = question.format(variable_bands[-1])
cents = int(input(q))
variable_bands.append(cents)
except (SyntaxError, ValueError):
variable_bands.append(0)
说“访问array.Symbol.iterator
变量的Symbol
成员,然后访问该值的array
成员”,但这将返回错误iterator
因为该数组没有名为Uncaught TypeError: Cannot read property 'iterator' of undefined
的成员,所以它返回Symbol
并且undefined
没有undefined
成员。
JS中的点iterator
运算符是左关联的,因此从左到右进行评估。您需要使用方括号来阐明所需的内容,以及所需的内容是访问.
的{{1}},然后使用该值访问iterator
变量的成员。>
要进行数学类比,Symbol
和array
之间的区别就像array.Symbol.iterator
(未定义,不能除以0)和array[Symbol.iterator]
( = 3,有效操作!)。
答案 2 :(得分:1)
因为这就是可迭代协议的工作方式。参见MDN:
可迭代协议允许JavaScript对象定义或自定义其迭代行为,例如for..of构造中循环的值。有些内置类型是具有默认迭代行为的内置迭代器,例如Array或Map,而其他类型(例如Object)则不是。
为了可迭代,对象必须实现@@ iterator方法,这意味着该对象(或其原型链中的一个对象)必须具有带有@@ iterator键的属性,该属性可通过常量Symbol获取。 .iterator:
解释器需要一种方法来确定泛型对象是否可迭代。尽管可以指定每个可迭代对象都有一个字符串iterator
属性,该属性在被调用时返回该对象的迭代器,但对于(迭代器)可能恰好具有该对象的对象可能是个问题。 iterator
属性,但不符合实际的规范迭代器协议。
要求通过(唯一的,特定于迭代器的)Symbol
访问iterator属性可确保不会发生此类有问题的冲突。
(作为旁注:array.Symbol.iterator
要求Symbol
是array
的属性,这没有多大意义-Symbol
是全局对象)