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

Oli*_*cal 1550 javascript

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

DRA*_*RAX 1761

这对我有用:

if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else
Run Code Online (Sandbox Code Playgroud)

  • @svth我记得.在JavaScript中,你可以有变量类型的字符串或对象类型,它是String类(同样的东西 - 都是字符串 - 但定义不同),这就是为什么要进行双重检查. (80认同)
  • -1因为这里的`instanceof`检查是无意义的噪音,除非你遵循一些*非常不寻常的*编码实践,这个答案没有解释它的作用或为什么你可以使用它.//google-styleguide.googlecode:你在任何时候需要它,如果你使用的包装对象,字符串,但包装的对象,字符串是没有人使用一个毫无价值的功能和谷歌都克罗克福德谴责坏的做法(HTTPS的唯一原因. COM/SVN /中继/ javascriptguide.xml?showone = Wrapper_objects_for_primitive_types#Wrapper_objects_for_primitive_types,http://www.crockford.com/javascript/recommend.html). (77认同)
  • "myVar instanceof String"是否做了"typeof myVar =='string'"之外的任何事情? (74认同)
  • 我强烈反对写出正确处理不太可能的案件的可靠代码是值得避免的.如果您的代码可能被其他人调用,那么检查`typeof`和`instanceof`就像是一个很好的建议.@ MarkAmery的`postmessage`边缘案件很重要,如果你问"我只是'postmessage`d是什么?" - 但是你希望在接口处理,不允许传播.在其他地方,处理非弃用的编码方法似乎是正确的,即使某些JS美学家对它们不赞成也是如此.永远不要将您的代码注释为接受String,除非确实如此! (62认同)
  • var somevar = new String('somestring')console.log(typeof somevar)// object (38认同)
  • 另外,如果你在代码中使用对象包装的字符串有一些疯狂的原因,那么值得注意的是,这里的函数不适用于跨框架代码; 它不会识别来自另一个帧的`postMessage`d的对象包装字符串,因为它们的构造函数将是来自*other*帧的`String`全局.这是一个不可能的假设情况,但既然你已经增加了复杂到您的解决方案使用包装的对象,字符串处理的人不可能假设情况*都*,我觉得它指向了合理的. (5认同)
  • 刚试过这个:alert(new String()instanceof String); 在FireFox中返回true(例如,alert(new Object()instanceof String);返回false). (4认同)
  • 总而言之,我不会将原始包装器称为“毫无价值的功能”,并且提供的代码一点也不罕见。他们有他们的用例。 (2认同)
  • 我认为你可以用 ```myVar.constructor === String``` 替换该条件,它适用于两种情况: ```myVar = "Foobar"``` 或 ```myVar = new String("Foobar ”)``` (2认同)
  • 我同意这是检查"噪音",但这是正确的答案.让我感到震惊的是,SO并没有把它移到顶端,因为它显然有更多的赞成. (2认同)
  • 谷歌。克罗克福德。好吧,好吧,无论如何。这个答案使用了 JavaScript 语言的基本语法和运算符。它显示了对当前基本形势的真正了解。优胜者。 (2认同)
  • @DRAX:缺少严格模式和扩展本机原型的副作用。如果您使用常规函数或在函数内添加“use strict”,原始版本将会更快(300 倍)。 (2认同)
  • @SmileyJames 这是正确的,`new String("somestring") instanceof String` 解析为 `true` (2认同)

Pab*_*ruz 1505

你可以使用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"
Run Code Online (Sandbox Code Playgroud)

此网页的示例.(虽然稍微修改了例子).

在使用创建的字符串的情况下,这将无法正常工作new String(),但很少使用和推荐[1] [2].如果您愿意,请参阅其他答案,了解如何处理这些问题.


  1. Google JavaScript样式指南说从不使用原始对象包装器.
  2. Douglas Crockford 建议弃用原始对象包装器.

  • 我的首选答案.反对它的论点是对于像`new String('foo')`这样的对象包装字符串'失败',但这并不重要,因为对象包装的字符串是一个你不应该使用的无用功能.谷歌风格指南[禁止他们](https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Wrapper_objects_for_primitive_types#Wrapper_objects_for_primitive_types),道格拉斯克罗克福德[希望他们弃用](http:// www. crockford.com/javascript/recommend.html),没有图书馆使用它们.假装他们不存在,并且毫无畏惧地使用`typeof`. (153认同)
  • @ Wolfy87请注意,在某些情况下,typeof stringValue可能会返回"object"而不是"string".请参阅我的回答评论. (43认同)
  • 没有[道格拉斯克罗克福德推荐'typeof`被弃用](http://www.crockford.com/javascript/recommend.html)? (7认同)
  • 如果它导致您头痛,99.99%的时间是因为您没有正确构建代码.这不是NaN对现有和做它所做的事情的错,这是你应该注意,学习和记住下次你使用可能产生它的代码时要记住的事情. (4认同)
  • @MarekMarczak 不确定我是否理解:NaN 是一个特殊的 IEEE 浮点值,绝对应该被视为使用 IEEE 浮点数的每种编程语言中的一个数字,其中的 _value_ 表示如果将其插入进一步的数学语句中,它将产生未定义的行为. 就像无穷大一样。 (3认同)
  • @DanielLe,因为他提出了可以解决某些问题的替代方案,而不是因为他原则上反对它。 (2认同)

Orw*_*ile 136

由于580多人投票给出了不正确的答案,800多人投票赞成了一个有效但霰弹枪式的答案,我认为以一种每个人都能理解的简单形式重新回答我的答案是值得的.

function isString(x) {
  return Object.prototype.toString.call(x) === "[object String]"
}
Run Code Online (Sandbox Code Playgroud)

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

Object.prototype.toString.call(myVar) === "[object String]"
Run Code Online (Sandbox Code Playgroud)

仅供参考,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 + ']';
    }; 
});
Run Code Online (Sandbox Code Playgroud)

那将定义isString,isNumber等.


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

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

  • @BenjaminGruenbaum我来寻找OP问题的答案,并不喜欢任何答案.所以我检查了下划线做了什么,并认为它足以提取和修改一点(以避免必须加载下划线库).我会澄清我的帖子. (17认同)
  • @Orwellophile,**这比DRAX的答案好吗?** (14认同)
  • 你推荐使用underscore.js(出于什么奇怪的原因?)但你不在这里使用它.此外,您使用函数污染全局命名空间.在node.js中你创建了一个具有所有这些函数的模块(你_can_使用`global || window`而不是`window`但是这对于解决你不应该在的问题是一个糟糕的方法.第一名). (11认同)
  • 我支持“错误答案”和“霰弹枪式答案”更具体地指代帖子,因为回复数量已经过时,然后还解释为什么这些答案较差,因为您提出了更好的答案。我的两分钱。 (6认同)
  • @Orwellophile Cool,我现在明白了,你原来的答案就像你在暗示下划线一样。就我个人而言,我只会检查 `myObject+"" === myObject` 来检查对象是否是字符串(或者更好的是,我不会首先在行为驱动的类型系统中键入检查)。 (4认同)
  • -1 因为与 [DRAX 的答案](/sf/answers/660586391/) 相比,这并没有真正添加任何内容,并且因为它表征了 [Pablo 的答案](https://stackoverflow.com/a /4059166/1709587) 不将 `new String("string")` 视为字符串而不提供任何参数说明为什么它应该被视为字符串是错误的。(IMO,它不应该是。对象包装的字符串与字符串不同,并且行为不同。TypeScript 同意我的观点;`const foo: string = new String("string")` 是一个编译错误。) (4认同)
  • @BenjaminGruenbaum `myObject+"" === myObject` 在`myObject = new String("string")` 的情况下不起作用。你必须使用`myObject instanceof String`。见 DRAX 的回答 (3认同)
  • JS支持猴子修补,因此可以在`Object.prototype`中重新定义`toString`.所以,我认为依靠`toString`检查对象的类型充其量只是一种不好的做法. (3认同)
  • 这不是一场人气竞赛。人们会使用最适合他们的答案。我喜欢我的答案,因为它通过示例表明用于检查类型的方法适用于许多对象类型。我喜欢一致的方法,并且喜欢 DRY 原则。我还喜欢这个答案来自最流行的 JS 库之一,并且已经在每个可以想象的平台和数千个真正的大网站上进行了测试。**向对象添加额外的功能只是一种不好的形式**。我也不会强迫任何人定义全局函数,只是提供一个更简单版本的 lodash 代码。 (3认同)
  • @Utopik 在那种情况下它不一样,原始值和包装值不一样。`String` 对象具有与字符串原始值类型完全不同的行为(例如尝试添加属性)。在这方面,德拉克斯的回答是错误的。 (2认同)
  • 对于有系统架构问题的人来说很酷的解决方案。 (2认同)
  • 供参考。`NaN` 是错误的。查看。`toString.call(1-"a") => "[对象编号]"`。但实际上`1-"a" ==> NaN` (2认同)
  • @Green `NaN` 仍然是 `Number` 的一个实例,特别是 `Number.NaN`。`typeof NaN` 也返回“数字”,以防其他人想知道。*无论哪种方式,它都不是一个字符串,这就是这个问题的内容。* (2认同)
  • 有趣的是,Array.isArray 正在成为一个标准函数,其推荐的填充实现与“Object.prototype.toString.call(arg) == '[object Array]'”相同。我不明白为什么不应该存在相同的方法 `String.isString = function(arg){return Object.prototype.toString.call(arg) == '[object String]';}`作品。我喜欢为其他类(如函数、数字等)定义这些迭代......但为什么会污染全局命名空间呢?为什么不效仿 Array.isArray 将它们添加为相应类型的“静态”方法? (2认同)

Cle*_*ud8 80

我建议使用jQuerylodash/Underscore中的内置函数.它们使用起来更简单,更易于阅读.

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

lodash/Underscore.js

if(_.isString(myVar))
   //it's a string
else
   //it's something else
Run Code Online (Sandbox Code Playgroud)

jQuery的

if($.type(myVar) === "string")
   //it's a string
else
   //it's something else
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这是JS社区出现问题的必要条件 - 对原始类型的检查是单行的,只涉及语言构造(基本的一种),但是建议使用外部库.如果某人已经使用了这些库中的一个,那么这可能是一个好主意,但只是为此而下载而不是简单地检查类型是一种矫枉过正. (85认同)
  • @RafałWrzeszcz这些库使用相当广泛,并提供了许多有用(和测试)的功能.特别是lodash.我不建议有人下载该库只用于这个解决方案....但我会建议每个javascript开发人员下载这个库,看看他们错过了什么.;) (19认同)
  • 所有你们都错过了像Lodash这样的图书馆:不是速度.不是"易于开发".**使用像Lodash这样的库的原因**提供了"防御性"来解决会破坏你的js app的问题.当您尝试对对象执行字符串操作时(或反之亦然)会发生致命错误,并且Lodash在防止这些错误方面提供了巨大的价值. (12认同)
  • 我要同意拉法尔.我到处都看到它提高了使用其中一个外部库的"可读性".如果您了解JavaScript,那么比您未使用的外部库更容易阅读.`_.every()`起初使用起来有点令人困惑,像`_.isBoolean()这样简单的东西让我公司的开发者感到困惑.如果值是布尔值并且为假,则开发人员错误地认为它将是错误的.对我来说,英语比德语更容易阅读,因为我不懂德语.学习JavaScript,这一切都有意义. (5认同)
  • 在生产中,您希望事情尽可能快地工作,虽然库显着缩短了开发时间,但它可能会通过添加抽象层来增加应用程序的复杂性。每个开发人员都必须研究该库才能使用它而不是“简单”的语言结构。要点是:如果你打算为你的应用程序使用一个库,只有当你知道你会做超过两三个单行或“检查”时才添加它:) (2认同)
  • 所有这些评论都是有效的,但是,伙计……只有使用 JS,使用第三方库来_检查类型_的建议才不会让你笑出开发室。 (2认同)

lin*_*ing 31

function isString (obj) {
  return (Object.prototype.toString.call(obj) === '[object String]');
}
Run Code Online (Sandbox Code Playgroud)

我在这看到:

http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/

  • 我认为这个解决方案是最强大的,因为它处理跨框架/跨窗口参考场景,如答案中提供的URL中所述. (3认同)
  • @ling只是好奇,为什么要在 `Object.prototype.toString.call(obj) === '[object String]'` 两边加上括号? (3认同)
  • 这与@Orwellophile 的回答有何不同? (2认同)

Cod*_*ody 25

最好的办法:

var s = 'String';
var a = [1,2,3];
var o = {key: 'val'};

(s.constructor === String) && console.log('its a string');
(a.constructor === Array) && console.log('its an array');
(o.constructor === Object) && console.log('its an object');
(o.constructor === Number || s.constructor === Boolean) && console.log('this won\'t run');
Run Code Online (Sandbox Code Playgroud)

其中每一个都是由适当的类函数构造的,比如"new Object()"等.

此外,鸭子打字:"如果它看起来像一只鸭子,像鸭子一样走路,闻起来像一只鸭子 - 它必须是一个数组"意思,检查它的属性.

希望这可以帮助.

编辑; 2016年12月5日

请记住,您也可以始终使用方法组合.以下是使用typeof内联动作映射的示例:

var type = { 'number': Math.sqrt.bind(Math), ... }[ typeof datum ];
Run Code Online (Sandbox Code Playgroud)

这是使用内联映射的更"真实世界"示例:

function is(datum) {
    var isnt = !{ null: true, undefined: true, '': true, false: false, 0: false }[ datum ];
    return !isnt;
}
console.log( is(0), is(false), is(undefined), ... );  // >> true true false
Run Code Online (Sandbox Code Playgroud)

此函数将使用[custom]"type-casting" - 而不是"type - / - value-mapping" - 来确定变量是否实际"存在".现在你可以在null&之间拆分那个讨厌的头发0!

很多时候你甚至不关心它的类型.绕过打字的另一种方法是组合Duck-Type集:

this.id = "998";  // use a number or a string-equivalent
function get(id) {
    if (!id || !id.toString) return;
    if (id.toString() === this.id.toString()) http( id || +this.id );
    // if (+id === +this.id) ...;
}
Run Code Online (Sandbox Code Playgroud)

两者Number.prototype String.prototype.toString() method.你只是确保数字的字符串等价物是相同的,然后你确保你把它http作为一个传递给函数Number.换句话说,我们甚至不关心它的类型.

希望能给你更多的工作:)

  • @torazaburo您可能想要使用断言(`(o.constructor === Number || s.constructor === Boolean)`).有趣的是,`parseInt`和`NaN`是脆弱但功能强大的工具.请记住,Not-a-Number不是非数字,可以定义未定义. (2认同)

Kam*_*ski 22

表现

今天 2020.09.17 我在 Chrome v85、Safari v13.1.2 和 Firefox v80 上针对选定的解决方案在 MacOs HighSierra 10.13.6 上执行测试。

结果

对于所有浏览器(以及两个测试用例)

  • 解决方案typeof||instanceof(A, I) 和x===x+''(H) 最快/最快
  • 解决方案_.isString(lodash lib)是中/快
  • 解决方案 B 和 K 最慢

在此处输入图片说明

更新:2020.11.28 我更新了x=123 Chrome列的结果- 对于解决方案I,之前可能存在错误值(= 69M 太低) - 我使用 Chrome 86.0 重复测试。

细节

我为解决方案执行 2 个测试用例 A B C D E F G H I J K L

  • 当变量是字符串时 - 你可以在这里运行它
  • 当变量不是字符串时 - 你可以在这里运行它

下面的片段显示了解决方案之间的差异

// https://stackoverflow.com/a/9436948/860099
function A(x) {
  return (typeof x == 'string') || (x instanceof String)
}

// https://stackoverflow.com/a/17772086/860099
function B(x) {
  return Object.prototype.toString.call(x) === "[object String]"
}

// https://stackoverflow.com/a/20958909/860099
function C(x) {
  return _.isString(x);
}

// https://stackoverflow.com/a/20958909/860099
function D(x) {
  return $.type(x) === "string";
}

// https://stackoverflow.com/a/16215800/860099
function E(x) {
  return x?.constructor === String;
}

// https://stackoverflow.com/a/42493631/860099
function F(x){
  return x?.charAt != null
}


// https://stackoverflow.com/a/57443488/860099
function G(x){
  return String(x) === x
}

// https://stackoverflow.com/a/19057360/860099
function H(x){
  return x === x + ''
}

// https://stackoverflow.com/a/4059166/860099
function I(x) {
  return typeof x == 'string'
}

// https://stackoverflow.com/a/28722301/860099
function J(x){
  return x === x?.toString()
}

// https://stackoverflow.com/a/58892465/860099
function K(x){
  return x && typeof x.valueOf() === "string"
}

// https://stackoverflow.com/a/9436948/860099
function L(x) {
  return x instanceof String
}

// ------------------
//     PRESENTATION
// ------------------

console.log('Solutions results for different inputs \n\n');
console.log("'abc' Str  ''  ' ' '1' '0'  1   0   {} [] true false null undef");

let tests = [ 'abc', new String("abc"),'',' ','1','0',1,0,{},[],true,false,null,undefined];

[A,B,C,D,E,F,G,H,I,J,K,L].map(f=> {  
console.log(
  `${f.name}   ` + tests.map(v=> (1*!!f(v)) ).join`   `
)})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>


This shippet only presents functions used in performance tests - it not perform tests itself!
Run Code Online (Sandbox Code Playgroud)

以下是 chrome 的示例结果

在此处输入图片说明


whe*_*ker 17

if (s && typeof s.valueOf() === "string") {
  // s is a string
}
Run Code Online (Sandbox Code Playgroud)

适用于字符串文字let s = 'blah'和对象字符串let s = new String('blah')

  • 注意力!这对于空字符串会失败,因为它们是错误的。 (8认同)

cus*_*der 14

我无法坦白地说为什么typeof在这种情况下不能简单地使用它:

if (typeof str === 'string') {
  return 42;
}
Run Code Online (Sandbox Code Playgroud)

是的,它将无法克服对象包装的字符串(例如new String('foo')),但是这些被广泛认为是不好的做法,并且大多数现代开发工具都可能会阻止其使用。(如果看到一个,请修复它!)

Object.prototype.toString诀窍是什么,所有的前端开发人员已经被判有罪在自己的职业生涯有一天会做,但不要让它通过其巧妙抛光欺骗你:这会尽快打破的东西猴子补丁对象的原型:

if (typeof str === 'string') {
  return 42;
}
Run Code Online (Sandbox Code Playgroud)

  • FWIW;因为对对象原型进行猴子修补可能会破坏该解决方案而反对该解决方案是一个薄弱的论点。在动态语言中,几乎任何事情都可能因为做不应该做的事情而被破坏! (4认同)
  • @Toolmaker史蒂夫·费尔。你当然是对的。有人可以轻松地改变所有原生原型,但一切都不再有效。我想我想表达的观点是,在猴子补丁仍然是常见做法的(JS)世界中,依赖这种技术充满了危险,当(更简单的)替代方案得到保证时,人们不应该将自己暴露在这种技术之下始终工作(据我所知,你不能猴子修补“typeof”)。尽管如此,这一点还是被采纳了。谢谢。 (3认同)

Sco*_*tyG 12

我喜欢使用这个简单的解决方案:

var myString = "test";
if(myString.constructor === String)
{
     //It's a string
}
Run Code Online (Sandbox Code Playgroud)

  • @Sheljohn Cody的回答很棒.我的答案(全文)更短,更直接.您询问... :) (3认同)
  • 与四年后的科迪的答案有何不同? (2认同)

Rob*_*der 11

这是性能重要的一个很好的例子:

如果没有正确完成,做一些像字符串测试一样简单的事情可能会很昂贵.

例如,如果我想编写一个函数来测试某些东西是否为字符串,我可以通过以下两种方式之一来完成:

1) const isString = str => (Object.prototype.toString.call(str) === '[object String]');

2) const isString = str => ((typeof str === 'string') || (str instanceof String));

这两个都很直接,所以可能会影响性能?一般来说,函数调用可能很昂贵,特别是如果你不知道里面发生了什么.在第一个示例中,有一个对Object的toString方法的函数调用.在第二个示例中,没有函数调用,因为typeof和instanceof是运算符.运算符明显快于函数调用.

测试性能时,示例1比示例2慢79%!

请参阅测试:https://jsperf.com/isstringtype


Ere*_*hen 9

我认为@customcommander 解决方案应该足以满足您 90% 的情况:

typeof str === 'string'
Run Code Online (Sandbox Code Playgroud)

应该为您服务(只是因为通常没有理由new String('something')在您的代码中使用)。

如果您也有兴趣处理该String对象(例如,您希望来自 3rd 方的一些 var),那么使用 lodash 作为@ClearCloud8 建议似乎是一个清晰、简单和优雅的解决方案。

但是,由于 lodash 的大小,我建议对诸如 lodash 之类的库保持谨慎。而不是做

import _ from 'lodash'
...
_.isString(myVar)
Run Code Online (Sandbox Code Playgroud)

这带来了整个巨大的 lodash 对象,我建议如下:

import { isString as _isString } from 'lodash'
...
_isString(myVar)
Run Code Online (Sandbox Code Playgroud)

通过简单的捆绑,你应该没问题(我在这里指的是客户端代码)。


Mar*_*hls 9

一种简单快速的测试方法是使用构造函数名称属性。

let x = "abc";
console.log(x.constructor.name === "String"); // true

let y = new String('abc');
console.log(y.constructor.name === "String"); // true
Run Code Online (Sandbox Code Playgroud)

表现

在此输入图像描述


Ben*_*cam 8

取自lodash:

function isString(val) {
   return typeof val === 'string' || ((!!val && typeof val === 'object') && Object.prototype.toString.call(val) === '[object String]');
}

console.log(isString('hello world!')); // true
console.log(isString(new String('hello world'))); // true
Run Code Online (Sandbox Code Playgroud)


Pat*_*ato 8

你可以使用这个函数来确定任何东西的类型:

var type = function(obj) {
    return Object.prototype.toString.apply(obj).replace(/\[object (.+)\]/i, '$1').toLowerCase();
};
Run Code Online (Sandbox Code Playgroud)

要检查变量是否为字符串:

type('my string') === 'string' //true
type(new String('my string')) === 'string' //true
type(`my string`) === 'string' //true
type(12345) === 'string' //false
type({}) === 'string' // false
Run Code Online (Sandbox Code Playgroud)

https://codepen.io/patodiblasi/pen/NQXPwY?editors=0012

要检查其他类型:

type(null) //null
type(undefined) //undefined
type([]) //array
type({}) //object
type(function() {}) //function
type(123) //number
type(new Number(123)) //number
type(/some_regex/) //regexp
type(Symbol("foo")) //symbol
Run Code Online (Sandbox Code Playgroud)

  • 这是一个可爱的小函数,尽管我个人不会使用它,而宁愿根据需要进行临时类型检查,例如 `foo === null` 或 `typeof foo == "string"`。投反对票 *可能* 是因为 1. 这可能有点不惯用;尽管使用 `Object.prototype.toString` 很常见,但我从未见过有人像您一样从结果中提取类型,仅与可能结果的精确值进行比较,例如 `"[object String]"` 2. 你不这样做不解释正则表达式的作用或原因,对于 JavaScript 新手来说,这可能非常不清楚,并且 3. 不清楚为什么比其他答案更喜欢这个。 (2认同)

Chr*_*hin 6

我也发现这也很好,而且比其他例子短得多.

if (myVar === myVar + '') {
   //its string
} else {
   //its something else
}
Run Code Online (Sandbox Code Playgroud)

通过连接空引号,它将值转换为字符串.如果myVar已经是字符串,则if语句成功.

  • 唯一的问题是当你想要检查它的类型时你是否强制变量.与`typeof`相比,这对我来说似乎有点贵. (4认同)
  • 这不适用于String类型; `var s = new String('abc'); > s === s +''> false` (4认同)
  • 我觉得这种做法令人反感。编写好的代码并不是让它变得“更短”。它是关于*说出你的意思*。 (2认同)

Tha*_*you 6

我发现这个简单的技术对字符串的类型检查很有用-

String(x) === x // true, if x is a string
                // false in every other case
Run Code Online (Sandbox Code Playgroud)

String(x) === x // true, if x is a string
                // false in every other case
Run Code Online (Sandbox Code Playgroud)

同样的技术也适用于Number -

Number(x) === x // true, if x is a number
                // false in every other case
Run Code Online (Sandbox Code Playgroud)

const test = x =>
  console.assert
    ( String(x) === x
    , `not a string: ${x}`
    )

test("some string")
test(123)           // assertion failed
test(0)             // assertion failed
test(/some regex/)  // assertion failed
test([ 5, 6 ])      // assertion failed
test({ a: 1 })      // assertion failed
test(x => x + 1)    // assertion failed
Run Code Online (Sandbox Code Playgroud)

对于正则表达式-

RegExp(x) === x // true, if x is a regexp
                // false in every other case
Run Code Online (Sandbox Code Playgroud)

Number(x) === x // true, if x is a number
                // false in every other case
Run Code Online (Sandbox Code Playgroud)

对象相同-

Object(x) === x // true, if x is an object
                // false in every other case
Run Code Online (Sandbox Code Playgroud)

注意,正则表达式、数组和函数也被视为对象。

const test = x =>
  console.assert
    ( Number(x) === x
    , `not a number: ${x}`
    )

test("some string") // assertion failed
test(123)           
test(0)             
test(/some regex/)  // assertion failed
test([ 5, 6 ])      // assertion failed
test({ a: 1 })      // assertion failed
test(x => x + 1)    // assertion failed
Run Code Online (Sandbox Code Playgroud)

但是,检查Array有点不同 -

Array.isArray(x) === x // true, if x is an array
                       // false in every other case
Run Code Online (Sandbox Code Playgroud)

RegExp(x) === x // true, if x is a regexp
                // false in every other case
Run Code Online (Sandbox Code Playgroud)

这种技术并没有对工作职能然而-

Function(x) === x // always false
Run Code Online (Sandbox Code Playgroud)

  • @unsynchronized 不过,“new String(x)”_应该_算作一个字符串并不明显。它是一个包装对象,具有与普通字符串不同的行为。除非您出于某种奇怪的原因对您希望检查如何处理字符串包装对象有具体要求(您可能没有,因为首先没有理由使用它们),否则这并不是真正反对这个答案。 (2认同)

Dav*_*vid 5

如果您在node.js环境中工作,则可以在utils中使用内置函数isString.

const util = require('util');
if (util.isString(myVar)) {}
Run Code Online (Sandbox Code Playgroud)

编辑:正如@Jehy所提到的,自v4以来已弃用.

  • 文档说“使用`typeof value === 'string'`代替。” (3认同)
  • `x = new String('x'); x.isString(x);` 返回 *false*。有 `util.types.isStringObject()` 但对于 `x = 'x'` 类型字符串返回 false。两个完全不提供任何实用功能的实用函数... (2认同)

Gra*_*ler 5

以下方法将检查任何变量是否为字符串(包括不存在的变量)。

const is_string = value => {
  try {
    return typeof value() === 'string';
  } catch (error) {
    return false;
  }
};

let example = 'Hello, world!';

console.log(is_string(() => example)); // true
console.log(is_string(() => variable_doesnt_exist)); // false
Run Code Online (Sandbox Code Playgroud)