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

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

答案

这对我有效:

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

您可以使用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] [2] 。如果您愿意,请参阅其他答案以了解如何处理这些问题。


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

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

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.exports = [
  'Arguments', 
  'Function', 
  'String', 
  'Number', 
  'Date', 
  'RegExp'
].reduce( (obj, name) => {
  obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
  return obj;
}, {});

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

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

我在这里看到了:

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

最好的办法:

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 。您只需确保与数字等效的字符串相同,然后确保将其作为Number传递给http函数。换句话说,我们甚至都不关心它的类型。

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

我无法坦白地说为什么在这种情况下不能简单地使用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'));

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

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

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

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

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

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

取自 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