检查变量是否是 JavaScript 中的字符串

IT技术 javascript string
2021-02-02 23:10:25

如何确定变量是字符串还是 JavaScript 中的其他内容?

6个回答

这对我有用:

if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else
我坚决不同意编写能够正确处理不太可能发生的情况的可靠代码是应该避免的。如果您的代码可能被其他人调用,请检查两者typeofinstanceof感觉是一个很好的建议。postmessage如果您问“我刚才是什么postmessage?”,@MarkAmery 的边缘案例很重要- 但您希望在接口处处理并且不允许传播。在其他地方,即使某些 JS 美学家不赞成它们,处理未弃用的编码方法似乎是正确的。切勿将您的代码注释为接受字符串,除非它确实如此!
2021-03-12 23:10:25
var somevar = new String('somestring') console.log(typeof somevar) // 对象
2021-04-02 23:10:25
-1 因为instanceof这里检查是毫无意义的噪音,除非您遵循一些非常不寻常的编码实践,并且这个答案没有解释它的作用或为什么您可能会使用它。您需要它的唯一原因是,如果您使用对象包装的字符串,但对象包装的字符串是一个没有人使用的毫无value的功能,Google 和 Crockford 都谴责为不好的做法(google-styleguide.googlecode.com/svn/行李箱/ ...crockford.com/javascript/recommend.html)。
2021-04-06 23:10:25
@svth 我记得。在 JavaScript 中,您可以拥有字符串类型的变量类型或字符串类型的对象类型(同一件事 - 两者都是字符串 - 但定义不同)这就是为什么要进行双重检查。
2021-04-08 23:10:25
"myVar instanceof String" 是否做任何超出 "typeof myVar == 'string'" 的事情?
2021-04-10 23:10:25

您可以使用typeof运算符:

var booleanValue = true; 
var numericalValue = 354;
var stringValue = "This is a String";
var stringObject = new String( "This is a String Object" );
alert(typeof booleanValue) // displays "boolean"
alert(typeof numericalValue) // displays "number"
alert(typeof stringValue) // displays "string"
alert(typeof stringObject) // displays "object"

来自此网页的示例(尽管示例略有修改)。

在用 创build 的字符串的情况下,这不会按预期工作new String(),但很少使用,建议不要使用[1][2]如果您愿意,请参阅其他答案以了解如何处理这些问题。


  1. Google JavaScript Style Guide说永远不要使用原始对象包装器
  2. Douglas Crockford建议弃用原始对象包装器
如果它让您头疼,那么 99.99% 的时间是因为您没有正确构建代码。这不是 NaN 存在并做它所做的事情的错,这是您在下次使用可能会产生它的代码时应该注意、学习并牢记的事情。
2021-03-17 23:10:25
@DanielLe,因为他提出了解决一些问题的替代方案,而不是因为他原则上反对。
2021-03-25 23:10:25
@Wolfy87 请注意,在某些情况下,typeof stringValue 可能会返回“object”而不是“string”。请参阅对我的回答的评论。
2021-04-02 23:10:25
我的首选答案。反对它的论点是它对于像 那样的对象包装字符串“失败” new String('foo'),但这无关紧要,因为对象包装字符串是您不应该使用的毫无value的功能。Google 风格指南禁止它们,Douglas Crockford希望它们被弃用,并且没有图书馆使用它们。假装它们不存在,然后放心使用typeof
2021-04-06 23:10:25

由于 580+ 人投票支持错误答案,800+ 人投票支持有效但霰弹枪式的答案,我认为可能值得以每个人都能理解的更简单的形式重做我的答案。

function isString(x) {
  return Object.prototype.toString.call(x) === "[object String]"
}

或者,内联(我有一个 UltiSnip 设置):

Object.prototype.toString.call(myVar) === "[object String]"

仅供参考,Pablo Santa Cruz 的回答是错误的,因为typeof new String("string")object

DRAX 的回答准确且实用,应该是正确的答案(因为 Pablo Santa Cruz 绝对是错误的,我不会反对大众投票。)

然而,这个答案也绝对是正确的,实际上是最好的答案(除了建议使用lodash / underscore)。免责声明:我为 lodash 4 代码库做出了贡献。

我的原始答案(显然是在很多人头上飞过)如下:

我从 underscore.js 转码:

['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'].forEach( 
    function(name) { 
        window['is' + name] = function(obj) {
              return toString.call(obj) == '[object ' + name + ']';
    }; 
});

这将定义 isString、isNumber 等。


在 Node.js 中,这可以作为一个module来实现:

module.exports = [
  'Arguments',
  'Function', 
  'String', 
  'Number', 
  'Date', 
  'RegExp'
].reduce( (obj, name) => {
  obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
  return obj;
}, {});

[编辑]:也Object.prototype.toString.call(x)用于描述函数和异步函数:

const fn1 = () => new Promise((resolve, reject) => setTimeout(() => resolve({}), 1000))
const fn2 = async () => ({})

console.log('fn1', Object.prototype.toString.call(fn1))
console.log('fn2', Object.prototype.toString.call(fn2))

你推荐 underscore.js(出于什么奇怪的原因?)但你不在这里使用它。此外,您会用函数污染全局命名空间。在 node.js 中,您将创建一个具有所有这些功能的module(您可以使用global || window而不是,window但这将是解决您一开始不应该遇到的问题的糟糕方法)。
2021-03-16 23:10:25
@BenjaminGruenbaum 我是来寻找 OP 问题的答案,但不喜欢任何答案。所以我检查了下划线做了什么,并认为它足以提取和修改一点(以避免必须加载下划线库)。我会澄清我的帖子。
2021-03-31 23:10:25
我支持“错误答案”和“霰弹枪式答案”更具体地参考帖子,因为回复的数量已经过时了,然后还解释了为什么这些答案在您提供优质答案时较差。我的两分钱。
2021-04-04 23:10:25
@Orwellophile,这比 DRAX 的答案好在哪里?
2021-04-05 23:10:25
JS 支持猴子补丁,因此可以toStringObject.prototype. 因此,我认为依靠toString检查对象的类型充其量是一种不好的做法。
2021-04-07 23:10:25

我建议使用jQuerylodash/Underscore的内置函数它们更易于使用且更易于阅读。

两个函数都将处理 DRAX 提到的情况……也就是说,它们检查(A)变量是字符串文字还是(B)它是 String 对象的实例。在任何一种情况下,这些函数都会正确地将该值标识为字符串。

lodash / Underscore.js

if(_.isString(myVar))
   //it's a string
else
   //it's something else

jQuery

if($.type(myVar) === "string")
   //it's a string
else
   //it's something else

有关更多详细信息,请参阅_.isString() 的 lodash 文档

有关更多详细信息,请参阅$.type() 的 jQuery 文档

这是 JS 社区问题的本质所在——检查原始类型是单行的,只涉及语言构建(基本类型之一),但您建议使用外部库。如果有人已经使用了这些库中的一个,这可能是一个好主意,但仅仅为此下载它们而不是简单地检查类型是一种矫枉过正。
2021-03-11 23:10:25
@RafałWrzeszcz 这些库使用相当广泛,并提供了许多有用(和经过测试)的功能。尤其是 lodash。我不会推荐某人下载该库仅用于这个解决方案......但我会建议每个 javascript 开发人员下载这个库,看看他们错过了什么。;)
2021-03-15 23:10:25
我同意 Rafal 的观点。我到处都看到使用这些外部库之一可以提高“可读性”。如果您了解 JavaScript,那么它比一些您没有使用过的外部库更容易阅读。 _.every()一开始使用起来有点混乱,就像_.isBoolean()我公司的开发人员一样简单开发人员错误地认为,如果该值为布尔值且为 false,则该值为 false。对我来说,英语比德语更容易阅读,因为我不会德语。学习 JavaScript,一切都会变得有意义。
2021-03-18 23:10:25
你们都错过了像 Lodash 这样的图书馆的重点:不是速度。不是“易于开发”。 使用 Lodash 之类的库的原因是提供了“防御”,以防止会炸毁您的 js 应用程序的问题。当您尝试对对象执行字符串操作时会发生致命错误(反之亦然),而 Lodash 在防止这些错误方面提供了巨大的value。
2021-03-29 23:10:25
所有这些评论都是有效的,但是,伙计......只有使用 JS 才会建议使用第三方库检查类型不会让你笑出开发室。
2021-04-01 23:10:25
function isString (obj) {
  return (Object.prototype.toString.call(obj) === '[object String]');
}

我在这里看到:

http://perfectkills.com/instanceof-thinked-harmful-or-how-to-write-a-robust-isarray/

@ling 只是好奇,你为什么要加上括号Object.prototype.toString.call(obj) === '[object String]'
2021-03-11 23:10:25
这与@Orwellophile 的回答有何不同?
2021-03-11 23:10:25
@Earlee 你的意思是(x === y)x === y?
2021-03-18 23:10:25
我认为这个解决方案是最健壮的,因为它可以处理答案中提供的 URL 中提到的跨框架/跨窗口引用场景。
2021-03-24 23:10:25
很好的答案,看起来 Underscore.js 也使用这种方法!
2021-03-26 23:10:25