【问题标题】:Type detection with a string in JavaScript?在 JavaScript 中使用字符串进行类型检测?
【发布时间】:2015-05-26 15:36:58
【问题描述】:

鉴于此:

function SomeType () { return this; }

我怎样才能只用一个字符串来检查一个对象的类型?

如果我有对构造函数的引用,那就太好了,就像这样:

new SomeType() instanceof SomeType; // true

但是如果我想检查类型为String,没有简单的方法检查。

new SomeType() instanceof 'SomeType'; // TypeError

我可以在构造函数转换为字符串后检查它:

function SomeType () { return this; }

/function \bSomeType\b/.test( String(new SomeType().constructor) ); // true

但并非在所有情况下都有效:

var SomeType = function () { return this; }

/function \bSomeType\b/.test( String(new SomeType().constructor) ); // false

对此有什么想法吗?尝试通过 String 验证类型/构造函数是否会被视为反模式?

【问题讨论】:

  • “尝试通过字符串验证类型/构造函数是否会被视为反模式?” 是的。这也是不可能的,正如您在var SomeType = function () { … }; 中看到的那样;该构造函数没有名称,因此您无法检查它。
  • @minitech 我也这么认为。我喜欢 JavaScript 的松散类型,直到它伤害到我为止。

标签: javascript types instanceof typeof


【解决方案1】:

如何将它与窗口对象进行比较?

new SomeType() instanceof window['SomeType']; // true

【讨论】:

  • 我想到了这个,但这将在高度模块化的 Node 应用程序中运行,原始构造函数将超出范围。
【解决方案2】:
function SomeType () { return this; }

var SomeType = function () { return this; };

是非常不同的陈述。第一个是函数声明,在脚本执行之前提升,并且在其定义范围内可用。后者是一个函数表达式,将一个未命名的匿名函数赋值给变量SomeType

在第一种情况下尝试匹配字符串 "SomeType" 就像将对象的构造函数解析为字符串 (new SomeType().constructor.toString()) 一样简单。在后一种情况下,SomeType 具有非常不同的含义:它是存储匿名函数的变量的名称。您需要一种完全不同的方法来获取对象的实例变量的名称,例如通过父对象执行for..in 循环以获取其属性名称。

如果您的代码是在假设函数声明和函数表达式在功能上相同的情况下编写的,那么您应该仔细重新检查代码。

如果您可以只检查函数声明(而不是包含函数表达式的变量名称),这是一个可行的方法:

function isType(obj,name){
    var constructor = obj.constructor.toString();
    return constructor.slice(9,constructor.indexOf("("))===name;
}

【讨论】:

  • 我很欣赏你的回答,我已经意识到匿名/命名函数之间的区别;但我的用例非常微妙。此外,您对命名函数的方法与我在问题中已经概述的方法基本相同。
  • 你是对的,这只是获取同一条信息的不同方式。但我认为您会发现obj.constructor.toString() 的性能比String(obj.constructor) 更好。根据我的经验,RegEx 在当前一代浏览器中也往往优化不佳,但未来可能会改变。这是一个用于调整选项的 jsperf:jsperf.com/stringifyingaconstructor
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 2017-08-25
  • 2014-03-09
  • 1970-01-01
  • 2011-05-24
  • 2020-08-05
相关资源
最近更新 更多