这篇文章是关于的Symbol()
,提供了我可以找到/制作的实际示例以及我可以找到的事实和定义。
TLDR;
的Symbol()
是数据类型,与ECMAScript的6(ES6)的版本中引入的。
关于符号有两个奇怪的事实。
JavaScript中的第一个数据类型,也是唯一的没有文字的数据类型
用定义的任何变量Symbol()
都会获得唯一的内容,但它并不是真正的私有。
任何数据都有其自己的符号,对于相同的数据,符号将是相同的。下一段中的更多信息,否则它不是TLRD;:)
如何初始化符号?
1.获取具有可调试值的唯一标识符
您可以通过以下方式之一进行操作:
var mySymbol1 = Symbol();
或者这样:
var mySymbol2 = Symbol("some text here");
该"some text here"
字符串不能从符号中提取,它只是用于调试目的的描述。它不会以任何方式改变符号的行为。但是,您可以console.log
这样做(由于值是用于调试的,所以很公平,以免将该日志与其他一些日志条目相混淆):
console.log(mySymbol2);
// Symbol(some text here)
2.获取一些字符串数据的符号
在这种情况下,实际上会考虑符号的值,因此两个符号可能是不唯一的。
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
我们将这些符号称为“第二类型”符号。它们不Symbol(data)
以任何方式与“第一类”符号(即用定义的符号)相交。
接下来的两段仅涉及第一种类型的符号。
使用Symbol代替旧的数据类型有什么好处?
首先让我们考虑一个对象,一种标准的数据类型。我们可以在那里定义一些键-值对,并可以通过指定键来访问这些值。
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
如果我们有两个叫Peter的人怎么办?
这样做:
var persons = {"peter":"first", "peter":"pan"};
不会有多大意义。
因此,似乎是两个绝对不同的人具有相同名称的问题。然后让我们指出new Symbol()
。就像现实生活中的一个人一样-任何人都是唯一的,但他们的名字可以相等。让我们定义两个“人”。
var a = Symbol("peter");
var b = Symbol("peter");
现在,我们有了两个同名的不同人。我们的人确实不同吗?他们是; 您可以检查以下内容:
console.log(a == b);
// false
我们在那里如何受益?
我们可以在您的对象中为不同的人输入两个条目,并且不能以任何方式将它们弄错。
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
注意:
不过,值得注意的是,用字符串化对象JSON.stringify
会删除所有以Symbol为键初始化的对。
执行Object.keys
不会返回这样的Symbol()->value
对。
使用此初始化,绝对不可能将输入的内容误认为第一人称和第二人称。呼叫console.log
他们会正确输出他们的名字。
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
在对象中使用时,与定义不可枚举属性相比有何不同?
实际上,已经存在一种定义要隐藏Object.keys
和枚举的属性的方法。这里是:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
Symbol()
带来什么不同?区别在于,您仍然可以Object.defineProperty
通过通常的方式获得使用定义的属性:
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
如果使用上一段中的Symbol进行定义:
fruit = Symbol("apple");
只有知道变量的值,您才能接收它的值,即
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
而且,在键下定义另一个属性"apple"
将使该对象删除较旧的属性(如果进行硬编码,则可能会引发错误)。因此,没有更多的苹果了!真可惜。参考上一段,这些符号是唯一的,并定义了一个Symbol()
使其唯一的键。
类型转换和检查
与其他数据类型不同,无法将转换Symbol()
为任何其他数据类型。
通过调用可以基于原始数据类型“制作”符号Symbol(data)
。
在检查类型方面,没有任何变化。
function isSymbol ( variable ) {
return typeof someSymbol === "symbol";
}
var a_Symbol = Symbol("hey!");
var totally_Not_A_Symbol = "hey";
console.log(isSymbol(a_Symbol)); //true
console.log(isSymbol(totally_Not_A_Symbol)); //false