检查值是否是 JavaScript 中的符号

问题描述 投票:0回答:4

如何在JS中检查一个值是否是Symbol?

我没有看到

Symbol.isSymbol(x)
方法。我的
(x instanceof Symbol)
测试似乎也不起作用。

javascript node.js ecmascript-6 symbols
4个回答
35
投票

用 typeof 检查一下:

typeof x === 'symbol'

7
投票

2022 年更新:采用已接受的答案! 如果您在一个过时的环境中工作,

Symbol
需要进行填充, 那么您已经知道了。你会非常痛苦地意识到这一点。你会被它“困扰”。那么,当然,使用我的答案。否则别打扰。 typeof x === 'symbol' 几乎绝对是您现在所需要的。

在 ES 2015 及更高版本中,只需要
typeof x === 'symbol'

即可。但如果您将代码转译为 ES 5.1 或更早版本,即使您使用内置的

Symbol
填充,它也不起作用。
我见过的每个 polyfill,包括 babel-polyfill,都使用名为 

typeof x === 'object'

的构造函数将 Symbol 实现为对象(即

Symbol
)。因此,在这些情况下,您可以检查
Object.prototype.toString.call (x) === '[object Symbol]'
*。
把它们放在一起,我们得到:

function isSymbol (x) { return typeof x === 'symbol' || typeof x === 'object' && Object.prototype.toString.call (x) === '[object Symbol]'; }

*请注意,我在转译场景中没有使用 

instanceof

instanceof
的问题在于,它只对在与断言相同的全局上下文中创建的对象返回 true。因此,如果网络工作者将一个符号传递回您的页面,或者在 iframe 之间传递符号,那么
x instanceof Symbol
将返回 false!对于所有对象类型(包括内置对象)始终都是如此。
instanceof
通常工作得很好,但如果您的代码有可能处于我所描述的“多帧”场景中,请谨慎使用!

    


0
投票

const result = (value && value.constructor === Symbol);



0
投票

typeof value=="symbol"

但是您可能不想依赖 
typeof

,因为对于已转换为对象的符号,它将返回

"object"
。这些符号仍然在各个方面发挥着符号的作用,不应该被忽视。
对于 ES6 之前的浏览器进行了多填充的符号在使用 

"object"

时也会返回

typeof
,因为
"symbol"
的返回类型在 ES6 之前尚不可用。
在这种情况下,使用 

instanceof

可能是你最好的选择:

Object(value) instanceof Symbol;// works in most cases

上面的方法比下面的最后一个方法更快,因为 try/catch 需要额外的开销。然而,
instanceof

在某些情况下会失败,例如在不同窗口或框架中创建的对象,因此在不同的全局环境中。

这里有一个方法可以解决以上所有问题。它可以与符号原语、无论全局环境如何都转换为对象的符号以及设计用于 ES6 之前的 JavaScript 的 polyfilled 

Symbol

一起使用。它起作用的原因是因为如果传递的值既不是符号也不是符号对象,

Symbol.prototype.toString()
将会抛出异常。
// Annoyingly complex, yet guaranteed to work

function isSymbol(value) {
    try {
        Symbol.prototype.toString.call(value)// Throws if value is not a Symbol primitive or object
        var isSymbol = 1;// This is only set if it didn't throw
    }
    catch(e) {
    }
    return !!isSymbol;// cast to boolean
}

© www.soinside.com 2019 - 2024. All rights reserved.