変数がJavaScriptの文字列かどうかを確認する


1742

変数がJavaScriptの文字列か何かであるかをどのように判断できますか?

回答:


1692

あなたは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]に対して推奨されません。必要に応じて、これらの処理方法について他の回答を参照してください。


  1. Google JavaScriptスタイルガイドでは、プリミティブオブジェクトラッパーを使用しないようにしています
  2. Douglas Crockford は、プリミティブオブジェクトラッパーを廃止することを推奨しました

45
@ Wolfy87 typeof stringValueが「string」ではなく「object」を返す場合があることに注意してください。私の答えについてのコメントを参照してください。
DRAX

163
私の好みの答え。それに対する反対論は、のようなオブジェクトラップされた文字列では「失敗」するnew String('foo')ということですが、オブジェクトラップされた文字列は使用すべきではない価値のない機能であるため、問題ではありません。グーグルのスタイルガイドはそれらを禁じており、ダグラス・クロックフォードはそれらを廃止することを望んでおり、どのライブラリもそれらを使用していません。それらが存在しないふりをして、typeof恐れることなく使用してください。
Mark Amery 2014


2
@DanielLe、それは彼がいくつかの問題を修正する代替品を提案したからであり、彼が原則としてそれに反対しているからではありません。
Vsevolod Golovanov 2017

4
それが頭痛の原因となる場合、99.99%の時間はコードを正しく構造化しなかったことが原因です。それは、既存のNaNのせいではなく、それが何をするかということではありません。これは、次にそれを生成する可能性のあるコードを操作するときに、注意し、学び、覚えておくべきことです。
Mike 'Pomax' Kamermans '10

1909

これは私にとってうまくいくものです:

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

77
"myVar instanceof String"は "typeof myVar == 'string'"以上のことを実行しますか?
2012

81
@svth思い出した。JavaScriptでは、可変型の文字列または文字列のクラスであるオブジェクトの型(同じもの-両方とも文字列です-定義が異なる)を使用できます。
DRAX

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

79
ありそうもないケースを正しく処理する確実なコードを書くことは避けるべきものだと私は精力的に反対しています。両方typeofをチェックしinstanceof、コードが他の人から呼び出される可能性がある場合は、良いアドバイスのように感じます。@MarkAmeryのpostmessageエッジケースは、「私はただpostmessagedだったのか?」-しかし、あなたはそれがインターフェースで処理され、伝播することを許可されないことを期待します。他の場所では、一部のJS麻酔医がそれらを承認しない場合でも、非推奨でないコーディング方法を処理することは正しいようです。本当にそうでない限り、文字列を受け入れるものとしてコードをコメントしないでください!
Dewi Morgan

157

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


11
(どのような奇妙な理由で)underscore.jsをお勧めしますが、ここでは使用しません。さらに、グローバル名前空間を関数で汚染します。node.js では、これらすべての機能を備えたモジュールを作成します(代わりに使用できます、そもそも、本来あるべきではない問題を解決するための悪いアプローチになります)。global || windowwindow
Benjamin Gruenbaum 2013

19
@BenjaminGruenbaum OPの質問の答えを探しに来たが、どれも気に入らなかった。だから私はアンダースコアが何をするかをチェックし、(アンダースコアライブラリをロードする必要を避けるために)少し抽出して修正するのに十分な気が利いていると思いました。私の投稿を明確にします。
Orwellophile 2013

2
@Orwellophile Cool、わかりました。元の回答は、アンダースコア自体を示唆しているようにフレーズ化されていました。個人的にはmyObject+"" === myObject、オブジェクトが文字列であるかどうかをチェックするだけです(または、そもそも動作ドリブンタイプシステムでタイプチェックを実行しないのが最初です)。
Benjamin Gruenbaum 2013

18
@Orwellophile、これはDRAXの答えよりどのように優れていますか?
パセリエ2017年

3
JSはモンキーパッチをサポートしているため、toStringでを再定義できますObject.prototype。したがって、toStringオブジェクトのタイプを確認することは、せいぜい、悪い習慣だと私は主張します。
アンドレロドリゲス

84

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ドキュメントを参照してください。


97
これはJSコミュニティの問題点の本質です。プリミティブ型に対するチェックは1行で、言語の構築(基本の1つ)のみを含みますが、外部ライブラリの使用をお勧めします。誰かがすでにこれらのライブラリの1つを使用している場合は良い考えかもしれませんが、単にタイプをチェックするのではなく、そのためだけにダウンロードするのはやり過ぎです。
ラファウWrzeszcz

5
私はラファルに同意します。これらの外部ライブラリのいずれかを使用することで「読みやすさ」が向上することは、どこでも見られます。JavaScriptを知っている場合は、使用していない外部ライブラリよりも読みやすくなります。 _.every()最初は少し混乱しますが_.isBoolean()、私の会社の開発者を混乱させたのと同じくらい簡単なものです。開発者は、値がブール値であり、偽である場合、誤って偽であると考えました。私はドイツ語を知らないので、英語はドイツ語よりも読みやすいです。JavaScriptを学ぶと、それはすべて理にかなっています。
ジョンハーディング

20
@RafałWrzeszczこれらのライブラリはかなり広く使用されており、非常に便利な(そしてテスト済みの)機能を提供します。特にロダッシュ。この1つのソリューションで使用するためだけにライブラリをダウンロードすることはお勧めしませんが、すべてのJavaScript開発者がこのライブラリをダウンロードして、不足しているものを確認することをお勧めします。;)
ClearCloud8 2017年

13
すべてのy'allには、Lodashのようなライブラリのポイントがありません。速度ではありません。「開発のしやすさ」ではありません。 Lodashのようなライブラリを使用する理由は、jsアプリを爆破する問題に対する「防御」を提供します。致命的なエラーは、オブジェクトに対して文字列操作(またはその逆)を実行しようとすると発生します。Lodashは、これらのエラーを回避することに関して多大な価値を提供します。
random_user_name 2017年

1
多くの人がNodeまたはNode-like環境でこれを行うことになることを覚えておいてください、そして、非常に少数の人々がそこでjQueryを使用するでしょう。
Matt Fletcher

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で言及されているクロスフレーム/クロスウィンドウの参照シナリオを処理するため、最も堅牢であると思います。
ewh、2015年

1
正解です。Underscore.jsもこのメソッドを使用しているようです。
2016

1
@ling気になるだけなのに、なぜ括弧を付けているのObject.prototype.toString.call(obj) === '[object String]'ですか?
StubbornShowaGuy

@Earlee (x === y)読みやすさよりもx === yいいですか?
StubbornShowaGuy 2017年

@StubbornShowaGuy私の意見では、はい。それは一貫性についてもです。個人的には、値を返すときに常に括弧を使用します。
Aquarelle 2018年

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()」などの適切なクラス関数によって構築されています。

また、アヒルのタイピング:「アヒルのように見え、アヒルのように歩き、アヒルのようなにおいがする場合-配列である必要があります」意味、そのプロパティを確認します。

お役に立てれば。

編集; 2016年5月12日

常にアプローチを組み合わせて使用​​することもできます。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。つまり、そのタイプを気にすることすらしませんでした。

それであなたがより多くの作業をすることを願っています:)


彼らのconstructorプロパティを取得しようとすることは失敗しますので、あなたは、昔ながらの数値のためのいくつかの他のチェックが必要になります

@torazaburoは今、Chromeコンソールでうまく動作しました。どうして機能しないと思いますか?
Mark Amery

2
@torazaburoアサーション((o.constructor === Number || s.constructor === Boolean))を試してみてください。逸話的に、parseIntそしてNaN壊れやすいが強力なツールです。Not-a-NumberはNot-a-Numberではなく、undefinedを定義できることを覚えておいてください。
Cody

1
a.constructorは===配列が間違っていると、時には失敗することができ、使用が見Array.isArray web.mit.edu/jwalden/www/isArray.htmlを
axkibe

1
同意しました、これはフェールセーフではありません。より良い方法は、プロパティチェックを使用することです。これが現時点で唯一の本当に安全な方法です。例:if(thing.call) { 'its a function'; }またはif(thing.defineProperties) { 'its an object'; }。入力をありがとう、axkibe!
コーディ

17

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


15

私はこの簡単な解決策を使いたいです:

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

3
それは、4年後のコーディの答えとどう違うのですか?
ジョナサンH

3
@Sheljohn Codyの答えはすばらしい。私の回答(完全なテキスト)は短く、要点はまっすぐです。あなたは尋ねました... :)
ScottyG

機能としては、これはに対処する方法が必要になるundefinednull、まだ右の空の文字列(両方のための答えを取得''してnew String(''))。
MikeBeaton

@MikeBeaton問題ありません(mystring || false) && mystring.constructor === String。ブール値を返す必要がある関数で使用される場合は、falseを使用しました。
アラン

13

これは、パフォーマンスが重要な理由の良い例です。

文字列のテストと同じくらい簡単なことを行うと、正しく行わないとコストが高くなる可能性があります。

たとえば、何かが文字列かどうかをテストする関数を記述したい場合、次の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


テストリンクは死んでいますが、私はあなたを信じています。この種の情報は非常に重要です。私見これは、最も賛成の回答ではないにしても、少なくとも現在の主要な回答について最も賛成のコメントでなければなりません。
Coderer、

typeof str === 'string' || str instanceof String(私がif (..)ケースで好むかっこを削除できます); とにかく、#2のプリミティブタイプとオブジェクトタイプの両方をチェックすることは明確で十分です。とにかく、これらのチェックは「まれ」です。
user2864740

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

文字列リテラルlet s = 'blah'とオブジェクト文字列の両方で機能しますlet s = new String('blah')


3
注意!空の文字列は誤っているため、これは失敗します。
Philipp Sumi


5

@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)

そして、単純なバンドルでは問題ないはずです(ここではクライアントコードを参照します)。


===なぜ==で十分なのか
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を返します。ユーティリティをまったく提供しない2つのユーティリティ関数...
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
}

空の引用符で連結することにより、値を文字列に変換します。if myVarがすでに文字列の場合、ifステートメントは成功します。


3
唯一の問題は、型をチェックしたいときに変数を強制していることです。と比較すると、それは私には少し高価に思えtypeofます。
Olical 2013

1
そうそう、あなたは正しい。jsperfによると、速度は約20%遅くなりますtypeofが、それでもかなり高速ですtoString。いずれにせよ、私は強制のための構文が好きだと思います。
クリスドルフィン

4
これは文字列型では機能しません。var s = new String('abc'); > s === s + '' > false
user5672998 2017年

1
new Stringタイプを作成するcus では機能しませんobjectw3schools.com/js/tryit.asp?filename=tryjs_string_object2
Chris Dolphin

良い考えですが、オブジェクトラップされた文字列のエッジケースは除外します。
Anthony Rutledge

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 === Stringがnullまたは未定義の場合もfalseを返す場合、nullまたは未定義を確認する必要があるのはなぜですか?
Jules Manson、

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でも機能します-

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)===xfalseを返します。ただし、({}).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()機能します
Muhammad Umer

7
@MuhammadUmerはい、それを文字列に変換しますが、元の値に対してIDをチェックします。元の値も文字列である場合にのみ、Trueになります。
MrWhite

4
これは間違ってい.toStringます。値を盲目的に呼び出すことはできません。チェックされるxがnullまたは未定義である場合、コードは例外をスローします
user5672998

1
アイデアはまだ使用可能です。x === String(x)は安全で機能します。
マートンサリー

本当に?このソリューションは私には奇妙すぎるようです。toString()メソッドがオーバーライドされ、例外がスローされる可能性があるため(特定の実装のため)、チェックが確実に機能しない場合があります。主な考え方は、取得したいものに関連しないメソッドを呼び出すべきではないということです。toStringメソッドに関連する不要なオーバーヘッドについても話していません。反対投票。
Rustem Zinnatullin

2

タイプチェッカーヘルパー:

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対照的に同じです。 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('');
    }
}

含まれているオプション

  • string-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とundefinedタイプも考慮され、などの非文字列タイプを処理し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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.