如何获取符号名称(文字)?
How can I obtain Symbol names (literals)?
以下情况:
var myVehicle = { brand: 'Tesla' };
var isMoving = Symbol();
var currentStatus = Symbol();
myVehicle[isMoving] = true;
myVehicle[currentStatus] = 'moving';
我想在我的对象 myVehicle
中打印使用过的 "Symbol-properties" 的名称
console.log(
myVehicle[isMoving], // true
myVehicle[currentStatus], // 'moving',
Reflect.ownKeys(myVehicle), // [ 'brand', Symbol(), Symbol() ]
Object.getOwnPropertySymbols(myVehicle), // [ Symbol(), Symbol() ]
);
我怎样才能得到这样的名字:
[isMoving, currentStatus]
而不是 [ Symbol(), Symbol() ]
这个问题真的没有意义。那些 variable 名称与它们引用的 Symbol 实例没有任何关系。构造Symbol时,可以给它一个字符串作为描述:
var isMoving = Symbol("isMoving");
当你console.log()
这样一个符号时,你会看到
Symbol(isMoving)
您可以使用 .toString()
获取描述,因此如果您想要来自所有 Symbol 属性的描述字符串:
var descrs = Object.getOwnPropertySymbols(obj).map(s => s.toString());
您遇到问题的原因是 Javascript 符号确实没有“名称”。
符号实际上没有名字
当您将一个符号分配给一个变量时,不会 给该符号一个跟在它后面的名称。
例如,考虑以下代码:
function getMeASymbol() {
var alpha = Symbol()
var beta = alpha
return beta
}
var gamma = getMeASymbol()
在函数内部,我们创建了一个符号并将其存储在 alpha
中。
然后我们将相同的符号存储在 beta
中。
最后,我们 return 符号,调用者将其存储在 gamma
中。
None 这三个变量名称确实附加到符号。
更重要的是,alpha
和 beta
在分配 gamma
时甚至不存在。
符号有描述
如果您在创建符号时传入描述,它会保留该字符串以供参考。
您可能会考虑符号的“名称”,尽管这些“名称”不一定是唯一的。
后面可以看到符号的.toString()
方法的return值里面的描述
console.log(Symbol('mySymbol').toString()) // prints "Symbol(mySymbol)"
如果你只想得到原始描述,你可以去掉多余的东西:
console.log(Symbol('mySymbol').toString().slice(7,-1))
更新 符号现在有一个 .description
属性,您可以使用它来代替调用 toString
并删除多余的字符。
console.log(Symbol('mySymbol').description)
结论
- 变量有名称。
- 一个变量将指向一个值。
- 符号是一种价值。
- 但是一个值不会指向包含它的任何变量。
- 所以你不能从值中获取变量名。
- 但是,如果您想在调试时查看一些有用的东西,请给出您的符号描述。
如@Pointy 和@Neall 所述,符号没有名称,但可以有描述。
以下是创建带有描述的符号的方法:
const isMoving = Symbol('isMoving');
访问此描述的方式如下:
console.log(isMoving.description); // Prints "isMoving"
属性description
还不是官方 EcmaScript 标准的一部分。在撰写本文时,它处于第 3 阶段。因此并非每个环境都支持它。有关详细信息,请参阅 the MDN article。
请注意,符号的描述与保存它的变量的名称无关。考虑以下因素:
const symbol1 = Symbol('Hello world!');
console.log(symbol1.description); // Prints "Hello world!", *not* "symbol1"
const symbol2 = symbol1;
console.log(symbol2.description); // Also prints "Hello world!"
以下情况:
var myVehicle = { brand: 'Tesla' };
var isMoving = Symbol();
var currentStatus = Symbol();
myVehicle[isMoving] = true;
myVehicle[currentStatus] = 'moving';
我想在我的对象 myVehicle
console.log(
myVehicle[isMoving], // true
myVehicle[currentStatus], // 'moving',
Reflect.ownKeys(myVehicle), // [ 'brand', Symbol(), Symbol() ]
Object.getOwnPropertySymbols(myVehicle), // [ Symbol(), Symbol() ]
);
我怎样才能得到这样的名字:
[isMoving, currentStatus]
而不是 [ Symbol(), Symbol() ]
这个问题真的没有意义。那些 variable 名称与它们引用的 Symbol 实例没有任何关系。构造Symbol时,可以给它一个字符串作为描述:
var isMoving = Symbol("isMoving");
当你console.log()
这样一个符号时,你会看到
Symbol(isMoving)
您可以使用 .toString()
获取描述,因此如果您想要来自所有 Symbol 属性的描述字符串:
var descrs = Object.getOwnPropertySymbols(obj).map(s => s.toString());
您遇到问题的原因是 Javascript 符号确实没有“名称”。
符号实际上没有名字
当您将一个符号分配给一个变量时,不会 给该符号一个跟在它后面的名称。 例如,考虑以下代码:
function getMeASymbol() {
var alpha = Symbol()
var beta = alpha
return beta
}
var gamma = getMeASymbol()
在函数内部,我们创建了一个符号并将其存储在 alpha
中。
然后我们将相同的符号存储在 beta
中。
最后,我们 return 符号,调用者将其存储在 gamma
中。
None 这三个变量名称确实附加到符号。
更重要的是,alpha
和 beta
在分配 gamma
时甚至不存在。
符号有描述
如果您在创建符号时传入描述,它会保留该字符串以供参考。
您可能会考虑符号的“名称”,尽管这些“名称”不一定是唯一的。
后面可以看到符号的.toString()
方法的return值里面的描述
console.log(Symbol('mySymbol').toString()) // prints "Symbol(mySymbol)"
如果你只想得到原始描述,你可以去掉多余的东西:
console.log(Symbol('mySymbol').toString().slice(7,-1))
更新 符号现在有一个 .description
属性,您可以使用它来代替调用 toString
并删除多余的字符。
console.log(Symbol('mySymbol').description)
结论
- 变量有名称。
- 一个变量将指向一个值。
- 符号是一种价值。
- 但是一个值不会指向包含它的任何变量。
- 所以你不能从值中获取变量名。
- 但是,如果您想在调试时查看一些有用的东西,请给出您的符号描述。
如@Pointy 和@Neall 所述,符号没有名称,但可以有描述。
以下是创建带有描述的符号的方法:
const isMoving = Symbol('isMoving');
访问此描述的方式如下:
console.log(isMoving.description); // Prints "isMoving"
属性description
还不是官方 EcmaScript 标准的一部分。在撰写本文时,它处于第 3 阶段。因此并非每个环境都支持它。有关详细信息,请参阅 the MDN article。
请注意,符号的描述与保存它的变量的名称无关。考虑以下因素:
const symbol1 = Symbol('Hello world!');
console.log(symbol1.description); // Prints "Hello world!", *not* "symbol1"
const symbol2 = symbol1;
console.log(symbol2.description); // Also prints "Hello world!"