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


1736

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

Answers:


1689

您可以使用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"

此网页中的示例。(尽管示例已稍作修改)。

在使用创建的字符串的情况下,这将无法正常工作new String(),但是很少使用这种方法,因此建议针对[1] [2]使用。如果您愿意,请参阅其他答案以了解如何处理这些问题。


  1. Google JavaScript样式指南说永远不要使用原始对象包装器
  2. 道格拉斯·克罗克福德(Douglas Crockford)建议不推荐使用原始对象包装器

45
@ Wolfy87请注意,在某些情况下,typeof stringValue可能会返回“对象”而不是“字符串”。看到我的答案评论。
DRAX 2012年

163
我的首选答案。反对它的说法是,它对于像那样的对象包装的字符串“失败” new String('foo'),但这没关系,因为对象包装的字符串是您不应该使用的毫无价值的功能。Google样式指南禁止使用它们,Douglas Crockford 希望弃用它们,并且没有库使用它们。假装它们不存在,并且typeof不用担心就可以使用。
Mark Amery 2014年


2
@DanielLe,因为他提出了可以解决某些问题的替代方案,而不是因为他原则上反对它。
Vsevolod Golovanov

4
如果它使您头痛,那么99.99%的时间是因为您没有正确构造代码。NaN并不存在现有的问题,也不是要做什么,这是您应该注意,学习的地方,并在下次使用可能产生这种结果的代码时牢记这一点。
Mike'Pomax'Kamermans

1905

这对我有效:

if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else

77
除了“ typeof myVar =='字符串'”之外,“ myVar instanceof String”是否还能做任何事情?
svth 2012年

81
我记得@svth。在JavaScript中,您可以具有字符串的可变类型或对象的类型,它是String的类(相同的东西-都是字符串-但定义不同),这就是为什么要仔细检查的原因。
DRAX 2012年

38
var somevar = new String('somestring')console.log(typeof somevar)//对象
Danubian Sailor

82
-1,因为instanceof除非您遵循一些非常不寻常的编码习惯,否则此处的检查是毫无意义的,并且此答案无济于事,不能解释其作用或使用原因。您唯一需要它的原因是,如果您使用对象包装的字符串,但是对象包装的字符串是一项没人使用的毫无价值的功能,而Google和Crockford都谴责这种作法(google-styleguide.googlecode.com/svn/行李箱/ ...crockford.com/javascript/recommend.html)。
Mark Amery

77
我非常不同意要避免编写能够正确处理不太可能的情况的可靠代码。同时检查两者typeofinstanceof如果您的代码可能被其他人调用,则感觉很好。@MarkAmery的极端postmessage情况很重要,如果您要问“我刚才是什么postmessage?” -但您希望该操作在接口上进行处理,并且不允许传播。在其他地方,即使某些JS美学不赞成使用不赞成使用的编码方法,这似乎也是正确的。除非它确实接受,否则决不要将您的代码注释为接受String!
Dewi Morgan Morgan 2015年

156

由于580多人投票支持一个错误的答案,而800多人投票支持一个可行的but弹枪式的答案,我认为值得以一种所有人都可以理解的简单方式重做我的答案。

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

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

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

仅供参考,巴勃罗圣克鲁斯的答案是错误的,因为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.exports = [
  'Arguments',
  'Function', 
  'String', 
  'Number', 
  'Date', 
  'RegExp'
].reduce( (obj, name) => {
  obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
  return obj;
}, {});

[edit]:也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))


11
您建议使用underscore.js(出于什么奇怪的原因?),但是您在这里不使用它。此外,您还会使用函数污染全局名称空间。在node.js中,您将创建一个具有所有这些功能的模块(您可以使用global || window代替,window但这将是解决您不应该首先解决的问题的不好的方法)。
本杰明·格伦鲍姆 Benjamin Gruenbaum)

19
@BenjaminGruenbaum我来寻找OP的问题的答案,但不喜欢任何答案。因此,我检查了下划线的作用,并认为提取和修改内容足够好(以避免必须加载下划线库)。我会澄清我的帖子。
Orwellophile

2
@Orwellophile酷,我明白了,您的原始答案的措辞就像您在建议加下划线。就个人而言,我只是检查myObject+"" === myObject对象是否为字符串(甚至更好,我首先不会在行为驱动的类型系统中进行类型检查)。
本杰明·格伦鲍姆

18
@Orwellophile,这比DRAX的答案更好吗?
Pacerier

3
JS支持猴子补丁,因此有可能重新定义toStringObject.prototype。因此,我认为依靠toString检查对象的类型充其量是一种不好的做法。
安德烈·罗德里格斯

84

我建议使用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

看到 更多详细信息, lodash的_.isString()文档

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


96
这是JS社区出了什么问题的本质-检查原始类型是一种方法,并且只涉及语言构造(基本的一种),但是建议您使用外部库。如果有人已经使用这些库中的一个,那可能是个好主意,但是仅仅为此下载它们而不是简单地检查类型是过大的选择。
拉斐尔·维尔泽斯卡(RafałWrzeszcz)

5
我要同意拉法。我到处都看到使用这些外部库之一可以提高“可读性”。如果您知道JavaScript,那么它比未使用的某些外部库更容易阅读。 _.every()一开始使用起来有点令人困惑,而且有些事情像_.isBoolean()使我公司的开发人员感到困惑一样简单。一个开发人员错误地认为,如果该值是布尔值并且为假,那将是假的。对我来说,英语比德语更容易阅读,因为我不懂德语。学习JavaScript,一切都会有意义。
约翰·哈丁

20
@RafałWrzeszcz这些库已被广泛使用,并提供了许多有用的(并经过测试的)功能。特别是lodash。我不建议有人下载该库仅用于此解决方案....但我建议每个javascript开发人员下载该库,然后看看他们遗漏了什么。;)
ClearCloud8

13
你们都错过了像Lodash这样的图书馆的要点:不是速度。不是“容易发展”。 使用Lodash之类的库的原因是针对可能导致js应用程序崩溃的问题提供“防御性”。尝试对对象执行字符串操作时会发生致命错误(反之亦然),Lodash为防止这些错误提供了巨大的价值。
random_user_name

1
请记住,许多人将在Node或类似Node的环境中执行此操作,并且很少有人在那里使用jQuery。
马特·弗莱彻

35
function isString (obj) {
  return (Object.prototype.toString.call(obj) === '[object String]');
}

我在这里看到了:

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


4
我认为此解决方案最可靠,因为它可以处理跨框架/跨窗口的参考方案,如答案中提供的URL中所述。
2015年

1
很好的答案,看来Underscore.js也使用此方法!
大安

1
@ling很好奇,为什么要加上括号Object.prototype.toString.call(obj) === '[object String]'
StubbornShowaGuy

@Earlee您的意思是(x === y)可读性比x === y
StubbornShowaGuy

@StubbornShowaGuy在我看来,是的。这也与一致性有关。返回值时,我个人总是使用括号。
水彩画

28

最好的办法:

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');

其中的每一个都由其适当的类函数构造而成,例如“ new Object()”等。

另外,Duck-Typing:“如果它看起来像鸭子,走路像鸭子,闻起来像鸭子-它必须是数组”,含义是,检查其属性。

希望这可以帮助。

编辑; 2016/12/05

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

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

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

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

此函数将使用[custom]“类型转换”(而不是“类型/值映射”)来确定变量是否确实“存在”。现在,您可以在null0!。

很多时候,您甚至都不关心它的类型。规避键入的另一种方法是组合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) ...;
}

两者Number.prototype String.prototype.toString() method。您只需确保与数字等效的字符串相同,然后确保将其http作为传递给函数Number。换句话说,我们根本不在乎它的类型。

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


您将需要其他一些检查纯旧数字的方法,因为尝试采用其构造函数属性将失败:

@torazaburo刚刚在Chrome控制台中对我来说工作正常。是什么让您认为它不起作用?
Mark Amery 2014年

2
@torazaburo您可能想玩断言((o.constructor === Number || s.constructor === Boolean))。有趣的是,parseIntNaN是脆弱的,但功能强大的工具。请记住,“非数字”不是“非数字”,并且可以定义undefined。
科迪2014年

1
a.constructor ===阵列错误,有时可能会失败,请使用Array.isArray参见web.mit.edu/jwalden/www/isArray.html
axkibe 2014年

1
同意,这不是故障安全的。更好的方法是使用属性检查-这是目前唯一真正的故障保护方法。例如:if(thing.call) { 'its a function'; }if(thing.defineProperties) { 'its an object'; }。感谢您的输入,axkibe!
科迪2014年

17

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

if (typeof str === 'string') {
  return 42;
}

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

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

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

console.log(isString('foo'));

Object.prototype.toString = () => 42;

console.log(isString('foo'));


15

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

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

3
与四年后的科迪的答案有何不同?
乔纳森·H

3
@Sheljohn Cody的答案很好。我的答案(全文)简短而直截了当。您问过... :)
ScottyG,

作为一个函数,这将需要一种处理undefined和的方法null,并且仍然可以正确回答空字符串(''new String(''))。
MikeBeaton

@MikeBeaton没问题:(mystring || false) && mystring.constructor === String。如果在必须返回布尔值的函数中使用了false,则使用false。
alans

13

这是表现为何如此重要的一个很好的例子:

如果测试不正确,那么像测试字符串这样简单的事情可能会很昂贵。

例如,如果我想编写一个函数来测试某物是否是字符串,则可以通过以下两种方式之一来进行操作:

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


测试链接已死,但我相信您。这种信息非常重要。恕我直言,这应该是,即使不是最受支持的答案,至少也应是对当前主要答案的最受支持的评论。
Coderer

typeof str === 'string' || str instanceof String(在if (..)某些情况下可以删除我更喜欢的括号);无论如何,检查#2中的原始类型和对象类型既清楚又充分。无论如何,这些检查应该是“稀有的”。
user2864740

12
if (s && typeof s.valueOf() === "string") {
  // s is a string
}

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


3
注意!对于空字符串,这将失败,因为它们是错误的。
菲利普·苏米


5

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

typeof str === 'string'

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

如果您有兴趣处理 String对象(例如,您希望第三者提供一些变量),则使用lodash作为@ ClearCloud8建议似乎是一个清晰,简单且优雅的解决方案。

但是,由于其大小,我建议谨慎使用lodash之类的库。而不是做

import _ from 'lodash'
...
_.isString(myVar)

这带来了整个巨大的lodash对象,我建议这样的事情:

import { isString as _isString } from 'lodash'
...
_isString(myVar)

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


为什么===当==足够时
zavr

4

如果您在node.js环境上工作,则只需在utils中使用内置函数isString。

const util = require('util');
if (util.isString(myVar)) {}

编辑:正如@Jehy所提到的,自v4起不推荐使用。


有替代品吗?
安东尼·孔

3
文档说“ typeof value === 'string'改为使用”。
罗杰斯先生

x = new String('x'); x.isString(x);返回false。有,util.types.isStringObject()但是对于x = 'x'字符串类型返回false 。两种实用程序功能绝对不提供实用程序...
spinkus

4

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

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

3

我还发现它也可以正常工作,并且比其他示例短很多。

if (myVar === myVar + '') {
   //its string
} else {
   //its something else
}

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


3
唯一的问题是,要检查变量的类型时要强制它。与相比,对我来说似乎有点贵typeof
Olical 2013年

1
是的,你是对的。jsperf表示,速度比慢20%,typeof但仍然比快很多toString。无论哪种方式,我想我都喜欢强制语法。
克里斯·海豚

4
这不适用于String类型;var s = new String('abc'); > s === s + '' > false
user5672998

1
不适new String用于创建的类型的cus objectw3schools.com/js/tryit.asp?filename=tryjs_string_object2
克里斯·海豚

好主意,但忽略了对象包装的字符串的边缘情况。
安东尼·鲁特里奇

3
var a = new String('')
var b = ''
var c = []

function isString(x) {
  return x !== null && x !== undefined && x.constructor === String
}

console.log(isString(a))
console.log(isString(b))
console.log(isString(c))

如果x.constructor ===字符串对于null或undefined也返回false,为什么还要检查null或undefined?
朱尔斯·曼森

1
@JulesManson:它将引发错误,而不是产生false
Ry-

3

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

String(x) === x // true, if x is a string
                // false in every other case

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

同样的技术也适用于过-

Number(x) === x // true, if x is a number
                // false in every other case

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

而对于正则表达式 -

RegExp(x) === x // true, if x is a regexp
                // false in every other case

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

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

对象相同-

Object(x) === x // true, if x is an object
                // false in every other case

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

const test = x =>
  console.assert
    ( Object(x) === x
    , `not an object: ${x}`
    )

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

但是,检查Array有点不同-

Array.isArray(x) === x // true, if x is an array
                       // false in every other case

const test = x =>
  console.assert
    ( Array.isArray(x)
    , `not an array: ${x}`
    )

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

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

Function(x) === x // always false

var x = new String(x); String(x)===x返回false。但是({}).toString.call(x).search(/String/)>0总是返回一些棘手的东西
不同步

1
function isClass(x,re){return ({}).toString.call(x).search(re)>0;}; isClass("hello",/String/)isClass(3,/Number/)isClass(null,/Null/)
不同步

2

一个简单的解决方案是:

var x = "hello"

if(x === x.toString()){
// it's a string 
}else{
// it isn't
}

1
这不会检查它是否是字符串。它变成了字符串,许多东西都toString()起作用了
穆罕默德·乌默尔

7
@MuhammadUmer是的,它将其转换为字符串,然后根据原始值检查身份,如果原始值也是字符串,则该值为True
MrWhite 2015年

4
这是错误的:您不能盲目调用.toString任何值;尝试检查要检查的x是否为null或未定义,您的代码将引发异常
user5672998

1
这个想法仍然有用。x === String(x)是安全的并且有效。
顿·萨里(MártonSári)

真?这个解决方案对我来说似乎太奇怪了,因为toString()方法可能会被覆盖并且可能引发异常(由于某些特定的实现),并且您的检查肯定无法进行。主要思想是您不应调用与您要获取的内容无关的方法。我什至没有在谈论与该toString方法相关的不必要的开销。投票失败。
Rustem Zinnatullin

2

Typechecker助手:

function isFromType(variable, type){
  if (typeof type == 'string') res = (typeof variable == type.toLowerCase())
  else res = (variable.constructor == type)
  return res
}

用法:

isFromType('cs', 'string') //true
isFromType('cs', String) //true
isFromType(['cs'], Array) //true
isFromType(['cs'], 'object') //false

另外,如果您希望它是递归的(例如作为对象的数组),则可以使用 instanceof

['cs'] instanceof Object //true


2

在这里,我将走另一条路,尝试告诉变量是特定类型还是特定类型集合的成员。
JS建立在鸭嘴式上。如果某些东西像字符串一样嘎嘎响,我们可以并且应该像字符串一样使用它。

7字符串吗?那为什么/\d/.test(7)行得通呢?
{toString:()=>('hello there')}字符串吗?那为什么({toString:()=>('hello there')}) + '\ngeneral kenobi!'行得通呢?
这些不是上面的工作应该做的问题,关键是它们确实在做。

因此,我做了一个duckyString()函数
下面,我测试了许多其他答案无法满足的情况。对于每个代码:

  • 设置类似字符串的变量
  • 对它运行相同的字符串操作,然后对真实的字符串进行比较以比较输出(证明可以将它们视为字符串)
  • 将类似字符串的形式转换为真实字符串,以向您展示duckyString()对期望真实字符串的代码的输入进行规范化
text = 'hello there';
out(text.replace(/e/g, 'E') + ' ' + 'hello there'.replace(/e/g, 'E'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');

text = new String('oh my');
out(text.toUpperCase() + ' ' + 'oh my'.toUpperCase());
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');

text = 368;
out((text + ' is a big number') + ' ' + ('368' + ' is a big number'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');

text = ['\uD83D', '\uDE07'];
out(text[1].charCodeAt(0) + ' ' + '😇'[1].charCodeAt(0));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');

function Text() { this.math = 7; }; Text.prototype = {toString:function() { return this.math + 3 + ''; }}
text = new Text();
out(String.prototype.match.call(text, '0') + ' ' + text.toString().match('0'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');

这是同样的!!x,而不是x===true和测试,如果事情是基于阵列的,而不是迫使实际阵列。
jQuery对象;他们是数组吗?不,他们够好吗?是的,您可以通过Array.prototype功能正常运行它们。
正是这种灵活性赋予了JS强大的功能,并字符串的专门使您的代码的互操作性降低。

上面的输出是:

hEllo thErE hEllo thErE
Is string? true "hello there"

OH MY OH MY
Is string? true "oh my"

368 is a big number 368 is a big number
Is string? true "368"

56839 56839
Is string? true "😇"

0 0
Is string? true "10"

因此,这就是为什么您想知道某个东西是否是字符串的全部原因
如果像我一样,您是从Google来到这里的,并且想看看是否是类似字符串的东西,那么这里就是一个答案。
除非您使用的是很长或深度嵌套的char数组,否则它甚至都不昂贵。
这是因为只有if语句,没有像这样的函数调用.toString()
除非您尝试查看一个char数组是否具有仅包含toString()'s或多字节字符的对象,在这种情况下,没有其他方法可以检查字符串,并分别计算字节组成的字符

function duckyString(string, normalise, unacceptable) {
    var type = null;
    if (!unacceptable)
        unacceptable = {};
    if (string && !unacceptable.chars && unacceptable.to == null)
        unacceptable.to = string.toString == Array.prototype.toString;

    if (string == null)
        ;

    //tests if `string` just is a string
    else if (
        !unacceptable.is &&
        (typeof string == 'string' || string instanceof String)
    )
        type = 'is';

    //tests if `string + ''` or `/./.test(string)` is valid
    else if (
        !unacceptable.to &&
        string.toString && typeof string.toString == 'function' && string.toString != Object.prototype.toString
    )
        type = 'to';

    //tests if `[...string]` is valid
    else if (
        !unacceptable.chars &&
        (string.length > 0 || string.length == 0)
    ) {
        type = 'chars';
        //for each char
        for (var index = 0; type && index < string.length; ++index) {
            var char = string[index];

            //efficiently get its length
            var length = ((duckyString(char, false, {to:true})) ?
                char :
                duckyString(char, true) || {}
            ).length;

            if (length == 1)
                continue;

            //unicode surrogate-pair support
            char = duckyString(char, true);
            length = String.prototype[Symbol && Symbol.iterator];
            if (!(length = length && length.call(char)) || length.next().done || !length.next().done)
                type = null;
        }
    }

    //return true or false if they dont want to auto-convert to real string
    if (!(type && normalise))
        //return truthy or falsy with <type>/null if they want why it's true
        return (normalise == null) ? type != null : type;

    //perform conversion
    switch (type) {
    case 'is':
        return string;
    case 'to':
        return string.toString();
    case 'chars':
        return Array.from(string).join('');
    }
}

包括的选项

  • 问哪种方法认为它是字符串-y
  • 排除字符串检测方法(例如,如果您不喜欢.toString()

这是更多测试,因为我是一名完成专家:

out('Edge-case testing')
function test(text, options) {
    var result = duckyString(text, false, options);
    text = duckyString(text, true, options);
    out(result + ' ' + ((result) ? '"' + text + '"' : text));
}
test('');
test(null);
test(undefined);
test(0);
test({length:0});
test({'0':'!', length:'1'});
test({});
test(window);
test(false);
test(['hi']);
test(['\uD83D\uDE07']);
test([['1'], 2, new String(3)]);
test([['1'], 2, new String(3)], {chars:true});
  • 所有负面的情况似乎都被解释了
  • 这应该在> = IE8的浏览器上运行
  • 具有字符串迭代器支持的浏览器支持具有多个字节的Char数组

输出:

Edge-case testing
is ""
null null
null null
to "0"
chars ""
chars "!"
null null
chars ""
to "false"
null null
chars "😇"
chars "123"
to "1,2,3"

1

只是为了扩展@DRAX的答案,我会这样做:

function isWhitespaceEmptyString(str)
{
    //RETURN:
    //      = 'true' if 'str' is empty string, null, undefined, or consists of white-spaces only
    return str ? !(/\S/.test(str)) : (str === "" || str === null || str === undefined);
}

它还将考虑nulls和undefinedtype,并将处理非字符串类型,例如0


1

这对我来说已经足够了。

警告:这不是一个完美的解决方案。请参阅我的帖子底部。

Object.prototype.isString = function() { return false; };
String.prototype.isString = function() { return true; };

var isString = function(a) {
  return (a !== null) && (a !== undefined) && a.isString();
};

您可以像下面这样使用。

//return false
isString(null);
isString(void 0);
isString(-123);
isString(0);
isString(true);
isString(false);
isString([]);
isString({});
isString(function() {});
isString(0/0);

//return true
isString("");
isString(new String("ABC"));

警告:在以下情况下,此方法无法正常工作:

//this is not a string
var obj = {
    //but returns true lol
    isString: function(){ return true; }
}

isString(obj) //should be false, but true

-1

您可以使用此函数来确定任何内容的类型:

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

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

type('my string') === 'string' //true
type(new String('my string')) === 'string' //true
type(`my string`) === 'string' //true
type(12345) === 'string' //false
type({}) === 'string' // false

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


-2

我不确定您是要知道它的类型是string什么,而不管它的内容是什么,还是内容是数字或字符串,而不管它的类型是什么。

因此,要知道其类型是否为字符串,就已经回答了。
但是要根据其内容知道它是字符串还是数字,我将使用以下代码:

function isNumber(item) {
    return (parseInt(item) + '') === item;
}

还有一些例子:

isNumber(123);   //true
isNumber('123'); //true
isNumber('123a');//false
isNumber('');    //false

我想我最初是在问如何检查类型,尽管那时我什至不知道如何提出问题。(我可能只是这样做/^\d+$/.test('123')以避免潜在的解析问题的复杂性)
Olical
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.