如何确定变量是字符串还是 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"
this webpage 中的示例。 (虽然示例稍作修改)。
在使用 new String()
创建的字符串的情况下,这不会按预期工作,但很少使用并建议反对[1][2]。如果您愿意,请参阅其他答案以了解如何处理这些问题。
Google JavaScript Style Guide 说永远不要使用原始对象包装器。 Douglas Crockford 建议弃用原始对象包装器。
new String('foo')
这样的对象包装字符串“失败”,但这并不重要,因为对象包装字符串是一个你不应该使用的毫无价值的功能。 Google 风格指南 forbids them、Douglas Crockford wants them deprecated,没有图书馆使用它们。假装它们不存在,并无所畏惧地使用 typeof
。
由于 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.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))
global || window
而不是 window
,但这是解决您不应该解决的问题的糟糕方法'首先没有)。
Object.prototype
中重新定义 toString
。因此,我认为依靠 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 Documentation for _.isString()。
有关详细信息,请参阅 jQuery Documentation for $.type()。
_.every()
起初使用起来有点令人困惑,而像 _.isBoolean()
这样简单的东西让我公司的开发人员感到困惑。开发人员错误地认为如果该值是布尔值并且是假的,那将是假的。对我来说,英语比德语更容易阅读,因为我不懂德语。学习 JavaScript,一切都会变得有意义。
编辑:目前的做法是typeof value === 'string'
。例如:
const str = 'hello';
if (typeof str === 'string') { ... }
自节点 v4 以来已弃用以下内容。
如果你在 node.js 环境下工作,你可以简单地使用 utils 中的内置函数 isString。
const util = require('util');
if (util.isString(myVar)) {}
typeof value === 'string'
”。
x = new String('x'); x.isString(x);
返回 false。有 util.types.isStringObject()
但对于 x = 'x'
类型的字符串返回 false。两个实用功能绝对不提供实用功能...
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]'
周围加上括号?
最好的办法:
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 月 5 日
请记住,您也可以随时使用方法组合。下面是使用带有 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 ] "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) ...;
}
Number.prototype
和 String.prototype
都有一个 .toString() method
。您只需确保数字的等效字符串相同,然后确保将其作为 Number
传递给 http
函数。换句话说,我们甚至不关心它的类型是什么。
希望这能给你更多的工作:)
(o.constructor === Number || s.constructor === Boolean)
)。有趣的是,parseInt
和 NaN
是脆弱但强大的工具。请记住,Not-a-Number 不是 Not-a-Number,并且可以定义 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'));
typeof
)。尽管如此。谢谢你。
Object.prototype.toString
使其返回不同的结果......坦率地说,这是他们的问题!恕我直言,这种可能性不应成为决定使用哪种方法的因素。 (我个人不打扰;我采用您展示的简单方法 - 但我不是在编写库代码。)
表现
今天 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 最慢
https://i.stack.imgur.com/cpaxI.png
更新: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 函数 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 函数 C(x) { return _.isString(x); } // https://stackoverflow.com/a/20958909/860099 函数 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 函数 F(x){ return x?.charAt != null } // https://stackoverflow.com/a/57443488/860099 函数 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('不同输入的解决方案结果\n\n'); console.log("'abc' Str '' ' ' '1' '0' 1 0 {} [] true false null undef");让测试 = [ '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` `)}) 这个shippet只展示了性能测试中使用的函数——它本身不执行测试!
这是 chrome 的示例结果
https://i.stack.imgur.com/oCOIh.png
new String("string")
创建的字符串,x + '' === x
失败。也许它应该仅限于正确的测试,或者至少为每个测试的结果添加列,例如 null
、undefined
、123
、new Object()
(都应该给出 false
) 和 ""
、"abc"
、new String("")
、new String("abc")
(都应该给出 true
)。
==
而不是 ===
得到了轻微的加速(至少在 macOS 上的 Chrome 中) - 但不确定这是否重要。
这是一个很好的例子,说明了为什么性能很重要:
如果没有正确完成,做一些像测试字符串这样简单的事情可能会很昂贵。
例如,如果我想编写一个函数来测试某个东西是否是字符串,我可以通过以下两种方式之一来完成:
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 中的原始类型和对象类型是清楚且足够的。无论如何,这些检查应该是“罕见的”。
Boolean(str.charCodeAt)
解决方案的唯一问题是它不能处理 undefined/null 的情况;否则我可以只说 const isString = str => str.charCodeAt !== undefined
以获得相同的性能
我喜欢使用这个简单的解决方案:
var myString = "test";
if(myString.constructor === String)
{
//It's a string
}
undefined
和 null
的方法,并且仍然为空字符串(''
和 new String('')
)获得正确的答案。
(mystring || false) && mystring.constructor === String
。我使用 false 以防它用于必须返回布尔值的函数。
.constructor
返回不同的答案?那将是相当令人惊讶的。
if (s && typeof s.valueOf() === "string") {
// s is a string
}
适用于字符串文字 let s = 'blah'
和对象字符串 let s = new String('blah')
取自 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
您可以使用此函数来确定任何事物的类型:
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
要检查其他类型:
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
foo === null
或 typeof foo == "string"
。否决票可能是因为 1. 这可能有点不习惯;尽管使用 Object.prototype.toString
很常见,但我从未见过有人像您一样将类型从结果中提取出来,只与可能结果的确切值进行比较,例如 "[object String]"
2.您没有解释正则表达式的作用或原因,对于 JavaScript 新手来说,这可能非常不清楚,并且 3. 不清楚为什么更喜欢这个而不是其他答案。
一种简单快速的测试方法是使用构造函数名称属性。
let x = "abc";
console.log(x.constructor.name === "String"); // true
let y = new String('abc');
console.log(y.constructor.name === "String"); // true
表现
https://i.stack.imgur.com/szABq.png
我发现这种简单的技术对 String 的类型检查很有用 -
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) // 断言失败 test(0) / / 断言失败 test(/some regex/) // 断言失败 test([ 5, 6 ]) // 断言失败 test({ a: 1 }) // 断言失败 test(x => x + 1) // 断言失败的
同样的技术也适用于 Number -
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") // 断言失败 test(123) test(0) test (/some regex/) // 断言失败 test([ 5, 6 ]) // 断言失败 test({ a: 1 }) // 断言失败 test(x => x + 1) // 断言失败
而对于正则表达式 -
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") // 断言失败 test(123) // 断言失败测试(0) // 断言失败 test(/some regex/) test([ 5, 6 ]) // 断言失败 test({ a: 1 }) // 断言失败 test(x => x + 1) // 断言失败的
对象相同 -
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") // 断言失败 test(123) // 断言失败测试(0) // 断言失败 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") // 断言失败 test(123) // 断言失败 test(0 ) // 断言失败 test(/some regex/) // 断言失败 test([ 5, 6 ]) test({ a: 1 }) // 断言失败 test(x => x + 1) // 断言失败
但是,此技术不适用于函数 -
Function(x) === x // always false
var x = new String(x); String(x)===x
返回错误。但是 ({}).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/)
new String(x)
应该 算作字符串并不明显。它是一个包装对象,具有与普通字符串不同的行为。除非您出于某种奇怪的原因对您希望您的检查如何处理字符串包装器对象有特定要求(您可能没有,因为首先没有理由使用它们),这并不是对这个答案的真正打击.
我还发现这也可以正常工作,并且比其他示例要短得多。
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
。
以下方法将检查任何变量是否为字符串(包括不存在的变量)。
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
is_string(x)
告诉我 x
是否是一个字符串,但它告诉我 x
是否是一个可调用的返回一个字符串。为什么我要传入一个函数而不是直接传递我的值?
is_string
函数用于检查变量是否存在并且是字符串。传递的箭头函数允许传递一个不存在的变量,而通常,如果变量不存在,我们会收到错误:“未捕获的 ReferenceError:变量未定义”。该用例类似于 PHP 中的错误控制运算符(即 is_string(@$example)
)。这可能不是最佳或最常见的做法,但有人可能会发现它很有用,这就是使这个答案与众不同的原因。
这对我来说已经足够好了。
警告:这不是一个完美的解决方案。请参阅我的帖子底部。
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 x = "hello"
if(x === x.toString()){
// it's a string
}else{
// it isn't
}
toString()
功能
.toString
;尝试如果要检查的 x 为 null 或未定义,您的代码会抛出异常
toString()
方法可能会被覆盖并且可能会抛出异常(由于某些特定的实现),并且您的检查肯定不会起作用。主要思想是你不应该调用与你想要得到的东西无关的方法。我什至没有谈论与 toString
方法相关的不必要的开销。投反对票。
类型检查器助手:
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()
function
在下面我测试了许多其他答案没有解决的案例。对于每个代码:
设置一个类似字符串的变量
对其运行相同的字符串操作和一个真实的字符串来比较输出(证明它们可以像字符串一样对待)
将类似字符串的字符串转换为真实字符串,以向您展示 dadyString() 以规范化需要真实字符串的代码的输入
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 强大的功能,而测试 for 字符串会特别降低您的代码的互操作性。
上面的输出是:
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"
所以,这就是为什么你想知道某个东西是否是字符串。
如果你像我一样从谷歌来到这里并想看看某些东西是不是类似字符串的 em>,这是一个答案。
除非您使用非常长或深度嵌套的 char 数组,否则它甚至不贵。
这是因为它都是 if 语句,没有像 .toString()
这样的函数调用。
除非您试图查看一个 char 数组是否包含只有 toString()
或多字节字符的对象,在这种情况下,除了创建字符串之外没有其他方法可以检查,并且分别计算字节组成的字符
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 上运行
支持字符串迭代器的浏览器支持多字节字符数组
输出:
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 的 answer,我会这样做:
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
和 undefined
类型,并将处理非字符串类型,例如 0
。
我有一个愚蠢的技术。但直截了当。
if(maybeAString.toUpperCase)
weHaveAString(maybeAString)
是的,它远非完美。但这很简单。
let x = 123; console.log(x.toUpperCase());
toUpperCase
与 toUpperCase()
不同
一个只有字符串没有任何数字的代码
isNaN("A") = true;
parseInt("A") = NaN;
isNaN(NaN) = true;
比我们可以使用 isNaN(parseInt()) 只有字符串
让 ignoreNumbers = "ad123a4m";让 ign = ignoreNumbers.split("").map((ele) => isNaN(parseInt(ele)) ? ele : "").join("");控制台.log(ign);
从 lodash 库 v4.0.0 实施
// getTag.js
const toString = Object.prototype.toString;
/**
* Gets the `toStringTag` of `value`.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function getTag(value) {
if (value == null) {
return value === undefined
? "[object Undefined]"
: "[object Null]";
}
return toString.call(value);
}
// isString.js
import getTag from "./getTag.js";
/**
* Checks if `value` is classified as a `String` primitive or object.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a string, else `false`.
* @example
*
* isString('abc')
* // => true
*
* isString(1)
* // => false
*/
function isString(value) {
const type = typeof value;
return (
type === "string" || (type === "object" &&
value != null &&
!Array.isArray(value) &&
getTag(value) == "[object String]")
);
}
export default isString;
我们也可以使用 isFinite() 而不是 typeof 或 isNAN() 检查这个:
var name="somename",trickyName="123", invalidName="123abc";
typeof name == typeof trickyName == typeof invalidName == "string" 🤷♀️
isNAN(name)==true
isNAN(trickyName)==false
isNAN(invalidName)==true 👀
在哪里:
isFinite(name) == false
isFinite(trickyName)== true
isFinite(invalidName)== true
所以我们可以这样做:
if(!isFinite(/*any string*/))
console.log("it is string type for sure")
请注意:
isFinite("asd123")==false
isNAN("asd123")==true
我不确定你的意思是知道它是否是类型 string
而不管其内容如何,或者它的内容是数字还是字符串,无论其类型如何。
所以要知道它的类型是否是字符串,已经回答了。
但是要根据它的内容知道它是一个字符串还是一个数字,我会使用这个:
function isNumber(item) {
return (parseInt(item) + '') === item;
}
对于一些例子:
isNumber(123); //true
isNumber('123'); //true
isNumber('123a');//false
isNumber(''); //false
/^\d+$/.test('123')
来避免潜在解析问题的复杂性)
instanceof
检查是毫无意义的噪音,除非您遵循一些非常不寻常的编码实践,而这个答案并不能解释它的作用或您可能使用它的原因。您需要它的唯一原因是如果您使用对象包装的字符串,但对象包装的字符串是没有人使用的毫无价值的功能,Google 和 Crockford 都谴责为不好的做法(google-styleguide.googlecode.com/svn/trunk/…、crockford.com/javascript/recommend.html)。typeof
和instanceof
感觉是个不错的建议。 @MarkAmery 的postmessage
边缘案例很重要,如果您问“我刚刚postmessage
做了什么?” - 但是您希望在界面上处理它并且不允许传播。在其他地方,处理未弃用的编码方法似乎是正确的,即使某些 JS 美学不赞成它们。切勿将您的代码评论为接受字符串,除非它确实如此!