回答:
あなたは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"
このWebページの例。(ただし、例はわずかに変更されました)。
これはnew String()
、で作成された文字列の場合は期待どおりに機能しませんが、これはめったに使用されず、[1] [2]に対して推奨されません。必要に応じて、これらの処理方法について他の回答を参照してください。
new String('foo')
ということですが、オブジェクトラップされた文字列は使用すべきではない価値のない機能であるため、問題ではありません。グーグルのスタイルガイドはそれらを禁じており、ダグラス・クロックフォードはそれらを廃止することを望んでおり、どのライブラリもそれらを使用していません。それらが存在しないふりをして、typeof
恐れることなく使用してください。
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
dだったのか?」-しかし、あなたはそれがインターフェースで処理され、伝播することを許可されないことを期待します。他の場所では、一部のJS麻酔医がそれらを承認しない場合でも、非推奨でないコーディング方法を処理することは正しいようです。本当にそうでない限り、文字列を受け入れるものとしてコードをコメントしないでください!
580人以上が間違った回答に投票し、800人以上が有効だがショットガンスタイルの回答に投票したので、誰もが理解できる簡単な形で私の回答をやり直す価値があると思いました。
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;
}, {});
[編集]: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
詳細については、_。isString()のlodashドキュメントを参照してください。
詳細については、$。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()」などの適切なクラス関数によって構築されています。
また、アヒルのタイピング:「アヒルのように見え、アヒルのように歩き、アヒルのようなにおいがする場合-配列である必要があります」意味、そのプロパティを確認します。
お役に立てれば。
常にアプローチを組み合わせて使用することもできます。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
。数値に相当する文字列が同じであることを確認し、それをhttp
として関数に渡したことを確認しましたNumber
。つまり、そのタイプを気にすることすらしませんでした。
それであなたがより多くの作業をすることを願っています:)
(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
トリックは、すべてのフロントエンド開発者が1日のキャリアで罪を犯していることが判明しているものですが、その巧妙な洗練に騙されないでください。何かがオブジェクトのプロトタイプにサルがパッチを当てるとすぐに壊れます。
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を使用しました。
これは、パフォーマンスが重要な理由の良い例です。
文字列のテストと同じくらい簡単なことを行うと、正しく行わないとコストが高くなる可能性があります。
たとえば、何かが文字列かどうかをテストする関数を記述したい場合、次の2つの方法のいずれかでそれを行うことができます。
1) const isString = str => (Object.prototype.toString.call(str) === '[object String]');
2) const isString = str => ((typeof str === 'string') || (str instanceof String));
これらはどちらも非常に単純明快なので、パフォーマンスに影響を与える可能性のあるものは何ですか?一般的に言えば、特に内部で何が起こっているのかわからない場合は、関数呼び出しは負荷が高くなる可能性があります。最初の例では、ObjectのtoStringメソッドへの関数呼び出しがあります。2番目の例では、typeofとinstanceofが演算子であるため、関数呼び出しはありません。演算子は関数呼び出しよりも大幅に高速です。
パフォーマンスをテストすると、例1は例2より79%遅くなります。
テストを参照してください:https : //jsperf.com/isstringtype
typeof str === 'string' || str instanceof String
(私がif (..)
ケースで好むかっこを削除できます); とにかく、#2のプリミティブタイプとオブジェクトタイプの両方をチェックすることは明確で十分です。とにかく、これらのチェックは「まれ」です。
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
@customcommanderソリューションはあなたのケースの90%で十分であるべきだと思います:
typeof str === 'string'
正しく機能するはずです(通常new String('something')
、コードに含める理由はありません)。
String
オブジェクトの処理にも興味がある場合(たとえば、サードパーティからのvarを期待している場合)、@ ClearCloud8が示唆するようにlodashを使用することは、明確でシンプルでエレガントなソリューションのように思えます。
ただし、サイズが大きいため、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を返します。ユーティリティをまったく提供しない2つのユーティリティ関数...
次のメソッドは、変数が文字列(存在しない変数を含む)かどうかをチェックします。
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
また、これも問題なく機能し、他の例よりもはるかに短いことがわかりました。
if (myVar === myVar + '') {
//its string
} else {
//its something else
}
空の引用符で連結することにより、値を文字列に変換します。if 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でも機能します-
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のために-
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
NB、正規表現、配列、関数もオブジェクトと見なされます。
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.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
メソッドに関連する不要なオーバーヘッドについても話していません。反対投票。
タイプチェッカーヘルパー:
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
対照的に同じです。
jQueryオブジェクト。それらは配列ですか?いいえ、十分ですか?ええ、あなたはそれらを関数を通してうまく動かすことができます。
JSにパワーを与えるのはこの柔軟性であり、文字列のテストは特にコードの相互運用性を低下させます。x===true
Array.prototype
上記の出力は次のとおりです。
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"
つまり、何かが文字列であるかどうかを知りたいのはそのためです。
私のように、あなたがグーグルからここに到着し、何かが文字列のようなものであるかどうかを確認したい場合、ここに答えがあります。
本当に長い、または深くネストされたchar配列を使用している場合を除き、コストはかかりません。
これは、すべてのifステートメントであり、などの関数呼び出しがないため.toString()
です。
ただし、toString()
'またはマルチバイト文字のみを含むオブジェクトを含むchar配列かどうかを確認しようとしている場合は例外です。
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
タイプも考慮され、などの非文字列タイプを処理し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')
潜在的な解析問題の複雑さを回避するために単に行うでしょう)