" Iterables"在JavaScript中是具有Symbol.iterator
属性的对象。例如:
let x = {
[Symbol.iterator]: function * () {
yield * [ 1, 2, 3];
}
};
[ ...x ] // Array [ 1, 2, 3 ]
所以Symbol.iterator
只是一个惯例。
但是,当Symbol
能够完成类似的工作时,为什么会发现这个概念string
?
let x = {
iterator: function * () {
yield * [ 1, 2, 3 ];
}
};
// Invalid, but would be equivalent to [ ...x['iterator']() ]
[ ...x ]
答案 0 :(得分:3)
Symbol.iterator
是一个符号,因此您无法复制或重新创建它。这消除了您可能意外覆盖它的可能性。
我建议您在JavaScript中观看有关Symbols的this video。
答案 1 :(得分:1)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
详细解释了符号特别是:
请注意,
Symbol("foo")
不会将字符串"foo"
强制转换为符号。它每次都会创建一个新符号:Symbol('foo') === Symbol('foo'); // false
假设我有一些数据要存储在一些广泛可见的对象中。我可以提出一个字符串,比如"foo"
,并将其用作将数据存储在对象中的键。稍后,我可以使用相同的字符串(硬编码或存储在某处)来将数据从对象中取出。
如果我们这样做,有两件事要记住:任何其他代码都可以查找我们的数据,任何其他代码都可以有意或无意地覆盖我们的数据(例如他们只是这样)碰巧选择了和我们一样的字符串。)
如果我们使用符号作为键,那么除非我们明确地给它们符号(例如作为参数),否则其他代码无法查找或修改数据。这样,冲突就不会发生,因为许多不同的代码都可以使用相同的字符串(如MDN示例中的"foo"
),但是它们总是会以不同的符号结束,所以&#? 39;没有冲突。
我们可能想要这样做的一个原因是,如果我们有一个单一的状态"各种代码将修改的对象。如果我们想保持每段代码的模块化,那么它们不会通过状态间接地相互依赖是非常重要的:通过使用符号,我们确保不仅一段代码不能改变别人的状态,但他们也不能依赖在其他人的状态(即根据读某人选择做什么)状态)。
答案 2 :(得分:0)
符号提供了一种可靠的方法来保证不会发生意外的属性名称冲突。字符串属性名称可能无意中被用于完全不同的目的。符号实例保证是唯一的;不可能创建两个比较为===
的Symbol实例。