Answers:
您可以使用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]使用。如果您愿意,请参阅其他答案以了解如何处理这些问题。
new String('foo')
,但这没关系,因为对象包装的字符串是您不应该使用的毫无价值的功能。Google样式指南禁止使用它们,Douglas Crockford 希望弃用它们,并且没有库使用它们。假装它们不存在,并且typeof
不用担心就可以使用。
这对我有效:
if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else
instanceof
除非您遵循一些非常不寻常的编码习惯,否则此处的检查是毫无意义的,并且此答案无济于事,不能解释其作用或使用原因。您唯一需要它的原因是,如果您使用对象包装的字符串,但是对象包装的字符串是一项没人使用的毫无价值的功能,而Google和Crockford都谴责这种作法(google-styleguide.googlecode.com/svn/行李箱/ ...,crockford.com/javascript/recommend.html)。
typeof
,instanceof
如果您的代码可能被其他人调用,则感觉很好。@MarkAmery的极端postmessage
情况很重要,如果您要问“我刚才是什么postmessage
?” -但您希望该操作在接口上进行处理,并且不允许传播。在其他地方,即使某些JS美学不赞成使用不赞成使用的编码方法,这似乎也是正确的。除非它确实接受,否则决不要将您的代码注释为接受String!
由于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))
global || window
代替,window
但这将是解决您不应该首先解决的问题的不好的方法)。
myObject+"" === myObject
对象是否为字符串(甚至更好,我首先不会在行为驱动的类型系统中进行类型检查)。
toString
的Object.prototype
。因此,我认为依靠toString
检查对象的类型充其量是一种不好的做法。
我建议使用jQuery或lodash / 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文档。
_.every()
一开始使用起来有点令人困惑,而且有些事情像_.isBoolean()
使我公司的开发人员感到困惑一样简单。一个开发人员错误地认为,如果该值是布尔值并且为假,那将是假的。对我来说,英语比德语更容易阅读,因为我不懂德语。学习JavaScript,一切都会有意义。
function isString (obj) {
return (Object.prototype.toString.call(obj) === '[object String]');
}
我在这里看到了:
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
Object.prototype.toString.call(obj) === '[object String]'
?
(x === y)
可读性比x === y
?
最好的办法:
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:“如果它看起来像鸭子,走路像鸭子,闻起来像鸭子-它必须是数组”,含义是,检查其属性。
希望这可以帮助。
请记住,您也可以始终使用方法的组合。这是在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]“类型转换”(而不是“类型/值映射”)来确定变量是否确实“存在”。现在,您可以在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) ...;
}
两者Number.prototype
并 String.prototype
有.toString() method
。您只需确保与数字等效的字符串相同,然后确保将其http
作为传递给函数Number
。换句话说,我们根本不在乎它的类型。
希望能给您更多的工作:)
(o.constructor === Number || s.constructor === Boolean)
)。有趣的是,parseInt
和NaN
是脆弱的,但功能强大的工具。请记住,“非数字”不是“非数字”,并且可以定义undefined。
if(thing.call) { 'its a function'; }
或if(thing.defineProperties) { 'its an object'; }
。感谢您的输入,axkibe!
我无法坦白地说为什么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
}
undefined
和的方法null
,并且仍然可以正确回答空字符串(''
和new String('')
)。
(mystring || false) && mystring.constructor === String
。如果在必须返回布尔值的函数中使用了false,则使用false。
这是表现为何如此重要的一个很好的例子:
如果测试不正确,那么像测试字符串这样简单的事情可能会很昂贵。
例如,如果我想编写一个函数来测试某物是否是字符串,则可以通过以下两种方式之一来进行操作:
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
typeof str === 'string' || str instanceof String
(在if (..)
某些情况下可以删除我更喜欢的括号);无论如何,检查#2中的原始类型和对象类型既清楚又充分。无论如何,这些检查应该是“稀有的”。
取自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
我认为@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)
通过简单的捆绑,您应该没事(我在这里指的是客户端代码)。
如果您在node.js环境上工作,则只需在utils中使用内置函数isString。
const util = require('util');
if (util.isString(myVar)) {}
编辑:正如@Jehy所提到的,自v4起不推荐使用。
typeof value === 'string'
改为使用”。
x = new String('x'); x.isString(x);
返回false。有,util.types.isStringObject()
但是对于x = 'x'
字符串类型返回false 。两种实用程序功能绝对不提供实用程序...
我还发现它也可以正常工作,并且比其他示例短很多。
if (myVar === myVar + '') {
//its string
} else {
//its something else
}
通过连接空引号,它将值转换为字符串。如果myVar
已经是一个字符串,则if语句成功。
typeof
。
var s = new String('abc'); > s === s + '' > false
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))
false
。
我发现这种简单的技术对于类型检查字符串很有用-
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
总是返回一些棘手的东西
function isClass(x,re){return ({}).toString.call(x).search(re)>0;};
isClass("hello",/String/)
或isClass(3,/Number/)
或isClass(null,/Null/)
一个简单的解决方案是:
var x = "hello"
if(x === x.toString()){
// it's a string
}else{
// it isn't
}
toString()
起作用了
.toString
任何值;尝试检查要检查的x是否为null或未定义,您的代码将引发异常
toString()
方法可能会被覆盖并且可能引发异常(由于某些特定的实现),并且您的检查肯定无法进行。主要思想是您不应调用与您要获取的内容无关的方法。我什至没有在谈论与该toString
方法相关的不必要的开销。投票失败。
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
)
在这里,我将走另一条路,尝试告诉变量是特定类型还是特定类型集合的成员。
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('');
}
}
包括的选项
.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});
输出:
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"
只是为了扩展@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);
}
它还将考虑null
s和undefined
type,并将处理非字符串类型,例如0
。
这对我来说已经足够了。
警告:这不是一个完美的解决方案。请参阅我的帖子底部。
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
您可以使用此函数来确定任何内容的类型:
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
我不确定您是要知道它的类型是string
什么,而不管它的内容是什么,还是内容是数字或字符串,而不管它的类型是什么。
因此,要知道其类型是否为字符串,就已经回答了。
但是要根据其内容知道它是字符串还是数字,我将使用以下代码:
function isNumber(item) {
return (parseInt(item) + '') === item;
}
还有一些例子:
isNumber(123); //true
isNumber('123'); //true
isNumber('123a');//false
isNumber(''); //false
/^\d+$/.test('123')
以避免潜在的解析问题的复杂性)