为什么JavaScript使用Symbols而不仅仅是字符串?

时间:2018-04-05 16:02:00

标签: javascript symbols

" 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 ] 

3 个答案:

答案 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实例。