如何获得符号名称(文字)?

Lon*_*ely 4 javascript symbols

以下情况:

var myVehicle = { brand: 'Tesla' };

var isMoving = Symbol();
var currentStatus = Symbol();

myVehicle[isMoving] = true;
myVehicle[currentStatus] = 'moving';
Run Code Online (Sandbox Code Playgroud)

我想在我的对象中打印使用过的“符号属性”的名称 myVehicle

console.log(
    myVehicle[isMoving],  // true
    myVehicle[currentStatus],  // 'moving',
    Reflect.ownKeys(myVehicle),  // [ 'brand', Symbol(), Symbol() ]
    Object.getOwnPropertySymbols(myVehicle), // [ Symbol(), Symbol() ]
);
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到这样的名字:

[isMoving, currentStatus] 代替 [ Symbol(), Symbol() ]

Nea*_*all 6

您遇到问题的原因是 Javascript 符号完全没有“名称”。

符号并没有真正的名字

当您将一个符号分配给一个变量时,并不会为该符号提供一个跟在它后面的名称。例如,考虑以下代码:

function getMeASymbol() {
  var alpha = Symbol()
  var beta = alpha
  return beta
}

var gamma = getMeASymbol()
Run Code Online (Sandbox Code Playgroud)

在函数内部,我们创建一个符号并将其存储在alpha. 然后我们将相同的符号存储在beta. 最后,我们返回符号,调用者将其存储在gamma. 这三个变量名都没有真正附加到符号上。更重要的是,alphabeta甚至不存在的时候gamma被分配。

符号确实有描述

如果您在创建符号时传入描述,它会保留该字符串以供参考。您可能会认为符号的“名称”,尽管这些“名称”不一定是唯一的。稍后,您可以在符号.toString()方法的返回值中看到描述。

console.log(Symbol('mySymbol').toString()) // prints "Symbol(mySymbol)"
Run Code Online (Sandbox Code Playgroud)

如果你只想得到原始描述,你可以去掉多余的东西:

console.log(Symbol('mySymbol').toString().slice(7,-1))
Run Code Online (Sandbox Code Playgroud)

update Symbols 现在有一个.description你可以使用的属性,而不是调用toString和剥离额外的字符。

console.log(Symbol('mySymbol').description)
Run Code Online (Sandbox Code Playgroud)

结论

  • 一个变量有一个名字。
  • 变量将指向一个值。
  • 符号是一种值。
  • 但是一个值并不指向包含它的任何变量。
  • 所以你不能从一个值中得到一个变量名。
  • 但是,如果您想在调试时查看一些有用的东西,请提供您的符号描述。


Poi*_*nty 5

这个问题真的没有意义。这些变量名与它们引用的 Symbol 实例没有任何关系。当你构造 Symbol 时,你可以给它一个字符串作为描述:

var isMoving = Symbol("isMoving");
Run Code Online (Sandbox Code Playgroud)

当你console.log()这样一个符号时,你会看到

Symbol(isMoving)
Run Code Online (Sandbox Code Playgroud)

您可以使用.toString()获取描述,因此如果您想要来自所有 Symbol 属性的描述字符串:

var descrs = Object.getOwnPropertySymbols(obj).map(s => s.toString());
Run Code Online (Sandbox Code Playgroud)

  • `console.log()` 显示的内容可能取决于浏览器,但描述的概念是它对于调试是可见的,所以控制台肯定*应该*显示它。 (2认同)