値がJavaScriptのオブジェクトかどうかを確認する


1365

値がJavaScriptのオブジェクトであるかどうかをどのように確認しますか?


4
変数は変数です。オブジェクトを参照する場合があります。また、「オブジェクト」を定義することもできます-回答とコメントが示すように、さまざまな矛盾する定義nullがあります(オブジェクトであるかどうかなど)。

8
OP、IMOあなたは@Daanの回答を受け入れる必要があります。これは最良の解決策であり、他の回答の上にリストして、最初に表示されるようにする必要があります。(良い答えも持っている他の人には
不快感

2
私見それは本当にあなた(この質問への回答を求めている人)がオブジェクトをどう考えているか、そしてなぜそれをチェックしているのかに依存します。この質問は、配列(オブジェクト)を他のオブジェクトから区別しようとしている場合、またはスカラー値を「ベクトル」から分離しようとしている場合に、異なる答えを示します。ヌル(つまり、かとあるのtypeofによると、オブジェクト)または(機能しているオブジェクト)を除外するかしない、それは本当にあなたがそれをチェックしている理由に依存します。だからこそ、非常に多くの答えがあり、それらのほとんどは、コンテキストでは正しいです。
FrancescoMM

const isEmpty = Thing => {Typeof Thing === "オブジェクト"?!もの|| !Object.keys(thing).length:!thing && thing!== 0};
Mayur S

1
「オブジェクトである」とは正確に何意味しているのかから始めることができればすばらしいと思います。(または、あなたが求めている答えの一部は、「オブジェクトである」というさまざまな一般的な意味を突き止め、それらを区別することであると明確に述べてください。
Don Hatch、

回答:


520

更新

この答えは不完全であり、誤解を招く結果になります。たとえば、他のいくつかのエッジケースは言うまでもなく、JavaScript nullのタイプとも見なさobjectれます。以下の推奨事項に従って、他の「最も賛成された(そして正しい!)回答」に進んでください


元の答え

typeof(var)またはを使用してみてくださいvar instanceof something

編集:この回答は変数のプロパティを調べる方法のアイデアを提供しますが、それが遠く離れたオブジェクトであるかどうかをチェックするための完全なレシピではありません(結局、レシピはまったくありません!)。人々は調査を行わずにここからコピーするものを探す傾向があるため、他の最も賛成された(そして正しい!)答えに目を向けることを強くお勧めします。


208
typeofは演算子なので、は必要ありません()
ヨシ

67
はい、必要ありません。私はこの方法を好むだけです。
マイケルクレリン-ハッカー、

150
@ MichaelKrelin-hacker:人を混乱させるので残念です。
RightSaidFred 2011

11
@RightSaidFred、私はそれについての説明はありませんが、これらの式に括弧を追加する気は絶対にありません:)
Michael Krelin-ハッカー

117
この答えは間違っています。typeofオブジェクトではないnullに対して 'object'を返し、をinstanceof使用して作成されたオブジェクトに対しては機能しませんObject.create(null)
ニコライ14

1635

の場合typeof yourVariable === 'object'、それはオブジェクトまたはnullです。nullを除外する場合は、単にnullにしますtypeof yourVariable === 'object' && yourVariable !== null


31
関数もオブジェクトであり、チェックに含める必要があります。
JS_Riddler

4
この場合yourVariable !== null、より良い練習になりますか?
ヒッピートレイル2013年

9
@RightSaidFred ES6ではtypeof null == 'object'修正されないようです。彼らは言った:This proposal has been rejected. It was implemented in V8 but it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
コンスタンチン・スモリャニン2013

2
@Orion簡単な答えは、配列はオブジェクトと見なされるということです。より詳細な回答を得るtypeofには、十分に理解できるとは限らないいくつかの特殊なケースがあるため、詳細を確認する必要があります。配列と配列ではないオブジェクトを区別しようとしている場合は、絶対にを使用しないでくださいtypeof
Matt Fenwick、2014

8
@Tresdin最善の方法は、実行することです。検査する必要Object.prototype.toString.call(yourVar)があるのはyourVarです。配列の場合、Object.prototype.toString.call([1,2])戻り値[object Array]
Jose Rui Santos

539

JavaScriptで「オブジェクト」を定義しましょうMDN docsによると、すべての値はオブジェクトまたはプリミティブのいずれかです。

プリミティブ、プリミティブ値

オブジェクトではなく、メソッドを持たないデータ。JavaScriptには、文字列、数値、ブール値、null、未定義の5つのプリミティブデータ型があります。

プリミティブとは何ですか?

  • 3
  • 'abc'
  • true
  • null
  • undefined

オブジェクトとは何ですか(プリミティブではありません)?

  • Object.prototype
  • すべての子孫 Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} -ユーザー定義関数
    • C.prototype-ユーザー定義関数のprototypeプロパティ:これはありません C sプロトタイプで
      • new C() -「新規」-ユーザー定義関数
    • Math
    • Array.prototype
      • 配列
    • {"a": 1, "b": 2} -リテラル表記を使用して作成されたオブジェクト
    • new Number(3) -プリミティブのラッパー
    • ... 他の多くのもの ...
  • Object.create(null)
  • すべての子孫 Object.create(null)

値がオブジェクトかどうかを確認する方法

instanceof 次の2つのケースがないため、それ自体では機能しません。

// oops:  isObject(Object.prototype) -> false
// oops:  isObject(Object.create(null)) -> false
function isObject(val) {
    return val instanceof Object; 
}

typeof x === 'object'誤検知(null)および誤検知(関数)のため、機能しません。

// oops: isObject(Object) -> false
function isObject(val) {
    return (typeof val === 'object');
}

Object.prototype.toString.call すべてのプリミティブの誤検知のため、機能しません。

> Object.prototype.toString.call(3)
"[object Number]"

> Object.prototype.toString.call(new Number(3))
"[object Number]"

だから私は使用します:

function isObject(val) {
    if (val === null) { return false;}
    return ( (typeof val === 'function') || (typeof val === 'object') );
}

@Daanの答えも機能するようです:

function isObject(obj) {
  return obj === Object(obj);
}

よると、理由はMDNドキュメント

Objectコンストラクターは、指定された値のオブジェクトラッパーを作成します。値がnullまたは未定義の場合は、空のオブジェクトを作成して返します。それ以外の場合は、指定された値に対応するタイプのオブジェクトを返します。値がすでにオブジェクトである場合、値を返します。


機能しているように見える3番目の方法(100%かどうかは不明)は、引数がオブジェクトでない場合に例外Object.getPrototypeOfスローする方法です。

// these 5 examples throw exceptions
Object.getPrototypeOf(null)
Object.getPrototypeOf(undefined)
Object.getPrototypeOf(3)
Object.getPrototypeOf('abc')
Object.getPrototypeOf(true)

// these 5 examples don't throw exceptions
Object.getPrototypeOf(Object)
Object.getPrototypeOf(Object.prototype)
Object.getPrototypeOf(Object.create(null))
Object.getPrototypeOf([])
Object.getPrototypeOf({})

22
obj === Object(obj)true配列を返します。
OnurYıldırım2016

5
var x = []; console.log(x === Object(x)); // return true
イルミネーター

6
@Illuminator配列、私の回答で述べたように、JavaScriptのオブジェクトです。
Matt Fenwick、2016

1
getPrototypeOfたとえば、オブジェクトであるがスローされる、取り消されたプロキシでは機能しません。
Oriol

2
({}).toString.apply(obj) === '[object Object]'これが配列と配列ではないオブジェクトを区別しないのはなぜですか
MauricioJuanes

295

underscore.jsは、何かが実際にオブジェクトであるかどうかを確認する次のメソッドを提供します。

_.isObject = function(obj) {
  return obj === Object(obj);
};

更新

V8の以前のバグとマイナーなマイクロ速度の最適化のため、underscore.js 1.7.0(2014年8月)以降、メソッドは次のようになります

_.isObject = function(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

57
JavaScriptで配列を使用すると、配列を除外したい時のため、ほとんど、また、オブジェクトである:return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
大安

22
なぜ配列を除外するのですか?彼らは本格的なオブジェクトです。
ニコライ14

65
たとえば、関数の入力として{}と[]を区別したい場合がほとんどです
Daan

5
@Nickolai ..ネストされたオブジェクトを反復するため。
リッキー・ボイス

6
すばらしい答えです。も扱いnullます。受け入れられる答えでなければなりません。
tiffon 2015年

180

Object.prototype.toString.call(myVar) 戻ります:

  • "[object Object]" myVarがオブジェクトの場合
  • "[object Array]" myVarが配列の場合

これの詳細と、typeofの代わりに使用できる理由については、こちらの記事をご覧ください。


12
私は最近それを学びましたtypeof [] === 'object'-> true。これがこのメソッドに必要なものです。
Jondlm 2013

3
@Christopheプリミティブとオブジェクトを区別しません。Object.prototype.toString.call(3)-> "[object Number]"Object.prototype.toString.call(new Number(3))-> "[object Number]"
マットフェンウィック

3
@MattFenwickこれは、OPが識別しようとしている「オブジェクト」の種類だとは思いません
Christophe

3
@Christopheなぜあなたはそれを思いますか?私見、OPによって「オブジェクト」について与えられた他の定義がない場合、ECS仕様全体で一貫して使用されているものを使用するのが私には最も合理的であるように思われます。
Matt Fenwick、2014年

getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Mr. Polywhirl 2014年

116

追加の関数呼び出し(速度)なしで単純にオブジェクトまたは配列をチェックします。こちらにも掲載しています

isArray()

isArray = function(a) {
    return (!!a) && (a.constructor === Array);
};
console.log(isArray(        )); // false
console.log(isArray(    null)); // false
console.log(isArray(    true)); // false
console.log(isArray(       1)); // false
console.log(isArray(   'str')); // false
console.log(isArray(      {})); // false
console.log(isArray(new Date)); // false
console.log(isArray(      [])); // true

isObject() -注:新しい日付や新しいYourCustomObjectなどのカスタムオブジェクトに対してfalseを返すため、オブジェクトリテラルのみに使用します。

isObject = function(a) {
    return (!!a) && (a.constructor === Object);
};
console.log(isObject(        )); // false
console.log(isObject(    null)); // false
console.log(isObject(    true)); // false
console.log(isObject(       1)); // false
console.log(isObject(   'str')); // false
console.log(isObject(      [])); // false
console.log(isObject(new Date)); // false
console.log(isObject(      {})); // true

isObjectオブジェクトリテラルでのみ機能します。私は、カスタムタイプを作成する場合は、型のインスタンスを作成し、それをテストし、それが返されますfalse
WickyNilliams

3
@zupa:!! aは何をしますか?

4
@ 3000は、nullとundefinedにコンストラクタがないため、(!! a)の部分を省略するとクラッシュします。(!! a)それらを除外します。それはあなたの質問に答えますか?
zupa 2015

2
@zupa @ 3000 Boolean(a)は長くなりますが、はるかに直感的です。使用しないでくださいnew Boolean(a):(ここに理由があります)!
JayVee

10
驚いたのは、これまでのところページの一番下の答えです。これは基本的に質問に答えます-これはJSONで{文字で始まるものとして表されますか?配列の場合、IE <9をサポートする必要がない限り、を使用Array.isArray()して、何かが配列かどうかを判断できます。あなたが提供したすべてのテストケースに合格します。
2016年

81

私は単純に好きです:

function isObject (item) {
  return (typeof item === "object" && !Array.isArray(item) && item !== null);
}

アイテムは、JSオブジェクトであり、それは、JSの配列ではありませんし、そうでない場合はnull... 3つのすべてが真、リターンを証明した場合true。3つの条件のいずれかが失敗すると、&&テストは短絡し、false返されます。null必要に応じてテストを省略することができます(ご使用方法に応じて、null)。

ドキュメント:

http://devdocs.io/javascript/operators/typeof

http://devdocs.io/javascript/global_objects/object

http://devdocs.io/javascript/global_objects/array/isarray

http://devdocs.io/javascript/global_objects/null


3
console.log(isObject(new Date()))はどうですか?なぜ日付はオブジェクトでなければならないのに配列はそうでないのですか?
schirrmacher、2015年

5
@macher new Date()オブジェクトを返すため。配列はオブジェクトではなく論理的な観点からのものです-JavaScriptはそれらをそのように処理して報告します。しかし実際には、それらが等しくないので、それらを等しく見ることは役に立ちません。lengthたとえば、オブジェクトには属性がなく、push()などのメソッドもありません。また、関数またはオーバーロードされたパラメーターを指定したい場合があります。特に、他のパラメーターが指定されたパラメーターに依存している場合は、配列またはオブジェクトを区別する必要があります。
StanE

1
@StanE配列は間違いなくオブジェクトです。あなたはオブジェクトが持つことができないと思う理由はわからないlengthようなプロパティやメソッドをpushObject.create(Array.prototype)これらを持っている非配列オブジェクトの些細な反例です。配列が特別なのは、配列がカスタム[[DefineOwnProperty]]必須の内部メソッドを持つエキゾチックなオブジェクトであるということですが、それでもオブジェクトです。
Oriol

4
@Oriol配列はオブジェクトではないことも、オブジェクトにlengthプロパティを設定できないことも書きませんでした(オブジェクトリテラルにはlengthデフォルトで属性がないことを意味します)。配列は論理的な観点からのオブジェクトではないことを書きました。私はプログラムロジックについて話している。配列が「実際の」配列であり、「実際の」オブジェクトではないことを確認する必要がある場合があります。それArray.isArray()が目的です。オブジェクトまたはオブジェクトの配列を受け入れる関数があるとします。特別な属性またはメソッドをチェックすることは、汚い解決策です。ネイティブの方法は常に優れています。
StanE

2
typeof null"object"、ではありません"undefined"
2540625 2016年

80

機能付きArray.isArray

function isObject(o) {
  return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}

機能なしArray.isArray

間違った回答に対する賛成票の数に驚いただけです😮 テストに合格した回答1
だけです!!! ここに私は私の簡単なバージョンを作成しました:

function isObject(o) {
  return o instanceof Object && o.constructor === Object;
}

私にとっては、それは明確でシンプルで、うまくいきます!ここに私のテスト:

console.log(isObject({}));             // Will return: true
console.log(isObject([]));             // Will return: false
console.log(isObject(null));           // Will return: false
console.log(isObject(/.*/));           // Will return: false
console.log(isObject(function () {})); // Will return: false

もう1回:すべての回答がこのテストに合格するわけではありません!!! 🙈


オブジェクトが特定のクラスのインスタンスであることを確認する必要がある場合は、次のように特定のクラスでコンストラクターを確認する必要があります。

function isDate(o) {
  return o instanceof Object && o.constructor === Date;
}

簡単なテスト:

var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d));   // Will return: true

その結果、厳格で堅牢なコードが作成されます。


、、などの関数を作成しない場合isDateisErrorisRegExpこの一般化された関数を使用するオプションを検討できます。

function isObject(o) {
  return o instanceof Object && typeof o.constructor === 'function';
}

前述のすべてのテストケースでは正しく機能しませんが、(プレーンまたは構築された)すべてのオブジェクトに対しては十分です。


isObjectObject.create(null)内部実装のためにここObject.createでは説明されていませんがisObject、より洗練された実装で使用できます:

function isObject(o, strict = true) {
  if (o === null || o === undefined) {
    return false;
  }
  const instanceOfObject = o instanceof Object;
  const typeOfObject = typeof o === 'object';
  const constructorUndefined = o.constructor === undefined;
  const constructorObject = o.constructor === Object;
  const typeOfConstructorObject = typeof o.constructor === 'function';
  let r;
  if (strict === true) {
    r = (instanceOfObject || typeOfObject) && (constructorUndefined || constructorObject);
  } else {
    r = (constructorUndefined || typeOfConstructorObject);
  }
  return r;
};

この実装に基づいて、npm v1にはすでにパッケージが作成されています!そして、それは前述のすべてのテストケースで機能します!🙂


ベストアンサー!ここで
プリーストン

これはisObject(myDateObject)に対してfalseを返すため、質問に対する回答ではありません。変数がオブジェクトであるかどうかはわかりません。特定のクラスのオブジェクトである場合のみです。ここでの質問は、任意のオブジェクトに対してtrueを返すジェネリック関数に関するものです。
Yetanotherjosh

@Yetanotherjoshそれは確かに答えです🤓あなたが答えで説明されているケースとポイントを述べました-あなたはisDate堅牢なコードを書く目的でyourDateObject に使用しなければなりませんisObject。そうでなければ、もろいメソッドがあります。
V. Kovpak

@VladimirKovpak使用 Dateはい、答えは議論してDateいるので、私のコメントでのは不適切な選択でした。しかし、これDateは無限の可能なクラスの1つにすぎず、他のクラスについても同じことが言えます。例:をclass Foo() { }; var x = new Foo(); isObject(x)返しますfalse。OPのユースケースは正確にはわかりませんが、考えられるすべてのクラスについて知っている必要があり、クラスごとに具体的にチェックすることが実行不可能になるシナリオは簡単に想像できます
Yetanotherjosh

@Yetanotherjosh私は私の答えを更新しました。そして、さらに1つのケースを追加しました。
V. Kovpak

41

何てことだ!これはこれまでよりも短くなると思います、これを見てみましょう:

短い最終コード

function isObject(obj)
{
    return obj != null && obj.constructor.name === "Object"
}

console.log(isObject({})) // returns true
console.log(isObject([])) // returns false
console.log(isObject(null)) // returns false

説明した

戻り型

typeof JavaScriptオブジェクト(を含むnull)が返されます"object"

console.log(typeof null, typeof [], typeof {})

コンストラクターの確認

それらのconstructorプロパティをチェックすると、名前付きの関数が返されます。

console.log(({}).constructor) // returns a function with name "Object"
console.log(([]).constructor) // returns a function with name "Array"
console.log((null).constructor) //throws an error because null does not actually have a property

Function.nameの紹介

Function.name関数または"anonymous"クロージャの読み取り専用の名前を返します。

console.log(({}).constructor.name) // returns "Object"
console.log(([]).constructor.name) // returns "Array"
console.log((null).constructor.name) //throws an error because null does not actually have a property

注: 2018年現在、Function.nameはIE で機能しない可能性がありますhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility


3
私は本当にこれが好きで、短くて要点があります。私の知る限り、1つの点で失敗するだけです。obj =の場合Object.create(null)、そしてとにかくなぜそうするのか...?
ジュリアンナイト

29

質問に答える前に、まずこの概念を説明しましょう。JavaScript関数ではObject、null、Object、Array、Dateもあるので、typeof obj === 'object'のような簡単な方法はありません。上記のすべてがtrue返しますが、関数を記述したりJavaScriptフレームワークを使用したりして確認する方法があります。OK:

ここで、実際のオブジェクト(nullでも関数でも配列でもない)であるこのオブジェクトがあるとします。

var obj = {obj1: 'obj1', obj2: 'obj2'};

純粋なJavaScript:

//that's how it gets checked in angular framework
function isObject(obj) {
  return obj !== null && typeof obj === 'object';
}

または

//make sure the second object is capitalised 
function isObject(obj) {
   return Object.prototype.toString.call(obj) === '[object Object]';
}

または

function isObject(obj) {
    return obj.constructor.toString().indexOf("Object") > -1;
}

または

function isObject(obj) {
    return obj instanceof Object;
}

上記のようにこれらの関数の1つをコードで呼び出すだけで使用でき、オブジェクトの場合はtrueを返します。

isObject(obj);

JavaScriptフレームワークを使用している場合、通常、次のような関数が用意されています。

jQuery:

 //It returns 'object' if real Object;
 jQuery.type(obj);

角度:

angular.isObject(obj);

アンダースコアとロダッシュ:

//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);

また、それが配列ではないことを確認する必要があります。so function isObject(obj){return obj!== null && typeof obj === 'object' &&!Array.isArray(obj); }
Matt Goo

私はあなたに同意しますが、コメントでわかるように、それはangularJsでどのように行われるかであり、私は関数の前のコメントでそれを言及します、それらはオブジェクトとして配列を数えます...詳細についてはここを見てください:docs .angularjs.org / api / ng / function / angular.isObject
Alireza

24

これは、「オブジェクトである」という意味によって異なります。プリミティブではないすべてのもの、つまり新しいプロパティを設定できるものが必要な場合は、これでうまくいくはずです。

function isAnyObject(value) {
    return value != null && (typeof value === 'object' || typeof value === 'function');
}

プリミティブ(プレーンな数値/ NaN/ Infinity、プレーンな文字列、シンボル、true/ falseundefinedおよびnull)は除外されますが、それ以外のすべて(およびを含むNumber)に対してはtrueを返す必要がBooleanありStringます。JSは、「ホスト」オブジェクト、のようなものを定義しないことに注意してくださいwindowまたはconsoleで使用した場合、返す必要がありますtypeof、それらは、このようなチェックでカバーするのは難しいですので、。

何かが「プレーン」オブジェクトであるかどうか、つまり、それがリテラル{}またはで作成されたかどうかを知りたい場合はObject.create(null)、次のようにします。

function isPlainObject(value) {
    if (Object.prototype.toString.call(value) !== '[object Object]') {
        return false;
    } else {
        var prototype = Object.getPrototypeOf(value);
        return prototype === null || prototype === Object.prototype;
    }
}

2018を編集Symbol.toStringTagの出力をカスタマイズできるようになったため、オブジェクトがリテラルとして開始された場合でも、上記Object.prototype.toString.call(...)isPlainObject関数がfalse場合によっては戻ることがあります。おそらく、慣例により、カスタム文字列タグを持つオブジェクトは、単なるプレーンオブジェクトではなくなりましたが、これにより、JavaScriptでのプレーンオブジェクトの定義がさらに複雑になっています。


typeof === 'function'がオブジェクトと見なされるのはなぜですか?関数はオブジェクトではありませんか?"new myFunc()"はオブジェクトになりますが、わかりやすい関数ですか?
StanE

いいえ、作成方法に関係なく、すべての関数はJavaScriptのオブジェクトです。(彼らは凍結していない限り)あなたは、彼らはそれらのプロパティを設定することができますinstanceof Objectなど、二つの同一の関数リテラルは厳密に等しくない、それらは参照によって渡され、
最後の子

21

私の神様、他の答えに混乱が多すぎます。

簡潔な答え

typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)

これをテストするには、Chromeコンソールで次のステートメントを実行します。

事例1。

var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true

事例2。

anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false

事例3。

anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false

説明

よし、分解してみよう

typeof anyVar == 'object'3つの候補からtrueが返されます- [], {} and null

anyVar instanceof Object これらの候補を2つに絞り込みます- [], {}

!(anyVar instanceof Array) 1つだけに狭まる- {}

ドラムロールください!

これで、Javascriptで配列をチェックする方法をすでに学習している可能性があります。


2
注目に値するのは、関数がのfalse場合anyVarは(必要に応じて)も返すことです。
ジェイミーバーチ

18

値の型をチェックする最も合理的な方法は、typeof演算子のようです。唯一の問題は、ひどく壊れていることです。

  • それは返す"object"ためにnullNull型に属する。
  • 戻る "function"、オブジェクトタイプに属する呼び出し可能なオブジェクトに対して。
  • 非標準の呼び出し不可能なオブジェクトに必要な(ほぼ)何でも返すことができます。たとえば、IEは気に入ったよう"unknown"です。禁止されている結果は"function"、プリミティブ型のみです。

typeofnullプリミティブに対してのみ信頼できます。したがって、値がオブジェクトであるかどうかを確認する方法は、によって返される文字列typeofがプリミティブに対応していないこと、およびオブジェクトがでないことを確認することですnull。ただし、問題は、将来の標準で新しいプリミティブ型が導入される可能性があり、コードではそれをオブジェクトと見なすことです。新しいタイプは頻繁には表示されませんが、たとえばECMAScript 6ではシンボルタイプが導入されました。

したがって、代わりに typeof、値がオブジェクトかどうかによって結果が異なるアプローチのみをお勧めします。以下は、

値がオブジェクトタイプに属しているかどうかをテストする適切な方法の包括的なリストですが、すべてではありません。

  • Object コンストラクタ

    Objectコンストラクタは、オブジェクトに渡される引数を強制します。すでにオブジェクトである場合は、同じオブジェクトが返されます。

    したがって、それを使用して値をオブジェクトに強制し、そのオブジェクトを元の値と厳密に比較できます。

    次の関数には、導入されたECMAScript 3が必要===です。

    function isObject(value) { /* Requires ECMAScript 3 or later */
      return Object(value) === value;
    }

    シンプルで自己記述的であり、類似のチェックがブール値、数値、文字列でも機能するため、このアプローチが好きです。ただし、それはグローバルObjectがシャドウされたり変更されたりしないことに依存していることに注意してください。

  • コンストラクタ

    コンストラクタをインスタンス化すると、作成したばかりのインスタンスとは異なる値が返される場合があります。しかし、それがオブジェクトでない限り、その値は無視されます。

    次の関数には、コンストラクターが非オブジェクトを返すことができるECMAScript 3が必要です。エラーをスローしたECMAScript 3以前は、tryステートメントが存在しませんでした。

    function isObject(value) { /* Requires ECMAScript 3 or later */
      return new function() { return value; }() === value;
    }

    前の例よりも少し単純ですが、これはグローバルプロパティに依存していないため、最も安全です。

  • this

    古いECMAScript仕様では、this値はオブジェクトである必要がありました。ECMAScript 3が導入されましたFunction.prototype.call。これにより、任意のthis値で関数を呼び出すことができましたが、オブジェクトに強制変換されました。

    ECMAScript 5は、この動作を削除するstrictモードを導入しましたが、sloppyモードでも、それを信頼できます(ただし、おそらくそうすべきではありません)。

    function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
      return function() { return this === value; }.call(value);
    }
  • [[プロトタイプ]]

    すべての通常のオブジェクトには、[[Prototype]]と呼ばれる内部スロットがあり、その値によって、他のオブジェクトから継承されます。値はオブジェクトまたはのみnullです。したがって、目的の値を継承するオブジェクトを作成して、それが機能するかどうかを確認できます。

    どちらObject.createObject.getPrototypeOfECMAScriptの5が必要です。

    function isObject(value) { /* Requires ECMAScript 5 or later */
      try {
        Object.create(value);
        return value !== null;
      } catch(err) {
        return false;
      }
    }
    function isObject(value) { /* Requires ECMAScript 5 or later */
      function Constructor() {}
      Constructor.prototype = value;
      return Object.getPrototypeOf(new Constructor()) === value;
    }
  • 新しいECMAScript 6の方法

    ECMAScript 6では、値がオブジェクトであることを確認するいくつかの新しい間接的な方法が導入されています。以前に見たアプローチを使用して、オブジェクトを必要とするコードに値を渡し、tryエラーをキャッチするためにステートメント内にラップします。コメントに値しないいくつかの隠された例


注:Object.getPrototypeOf(value)(ES5)やReflectメソッド(ES6 )などのいくつかのアプローチは意図的にスキップしましたvalue。これは、プロキシの場合など、厄介なことを行う可能性のある重要な内部メソッドを呼び出すためです。安全上の理由から、私の例はvalue直接アクセスすることなく参照するだけです。


2
「私の答えとダーンだけが完全に正しい。」私はあなたの最初の2つの文に完全に同意ないことを考えると、少しおかしいです。
zzzzBov 2016

1
@zzzzBovさて、私はすべての回答を調べましたが、私の回答とDaanの回答を除いて、常に正しい回答が返されるとは限りません。私はそれらのほとんどに再現可能な反例を与えることができます。他の人はtypeofが「関数」または「オブジェクト」を返すかどうかをチェックすることを推奨しますが、私が説明したように、仕様はいくつかのオブジェクトに対して他の結果を許可します。マットフェンウィックの回答には、ダーンと同じ正しい回答が含まれていますが、不正解も含まれています。
Oriol

1
私はあなたの答えが「完全に正しい」という前提に反対し、他の人が「常に正しい答えを返すことを保証していない」とは決して私の立場に反論しないと主張しました。さらに、この質問では、どの入力がどの出力を生成する必要があるかについての主張はありません。
zzzzBov 2016

1
@zzzzBov質問は、何かがオブジェクトであるかどうかを確認する方法を尋ねます。ECMAScriptはオブジェクトとは何かを定義するので、私はその定義を使用します。他の合理的な解釈は見当たらない。他のことを行う回答(配列の除外など)は、状況によっては役立つ場合がありますが、何かがオブジェクトであるかどうかはチェックしません。
Oriol


15

これを試して

if (objectName instanceof Object == false) {
  alert('Not an object');
}
else {
  alert('An object');
}

14
ブール値をチェックするのはなぜですか?
jkutianski 2013

5
これは2つのケースを見落としObject.prototype instanceof Objectます:-> false。 Object.create(null) instanceof Object-> false。
Matt Fenwick 2014年

日付はどうですか?new Date() instanceof Object => true
mauron85

13

チェック用の関数を使用する準備ができました

function isObject(o) {
  return null != o && 
    typeof o === 'object' && 
    Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
  return !isObject(o) && 
    null != o && 
    (typeof o === 'object' || typeof o === 'function') &&
    /^\[object /.test(Object.prototype.toString.call(o));
}

// Loose equality operator (==) is intentionally used to check
// for undefined too

// Also note that, even null is an object, within isDerivedObject
// function we skip that and always return false for null

説明

  • JavaScriptでは、nullObjectArrayDateおよびfunctionSは、すべてのオブジェクトです。しかし、null少し工夫されています。したがって、null最初のものをチェックして、それがnullではないことを検出することをお勧めします。

  • オブジェクトであるtypeof o === 'object'保証のチェックo。このチェックがなければ、Object.prototype.toStringそれもために、everthingのためのオブジェクトを返しますから、意味がないundefinednull!次に例を示しtoString(undefined)ます。[object Undefined]

    typeof o === 'object'チェック後、toString.call(o)oは、オブジェクト、のような派生オブジェクトArrayDateまたはであるかどうかをチェックするのに最適なメソッドfunctionです。

  • isDerivedObject機能、それがチェックするo機能です。関数もオブジェクトなので、そこにあるのはそのためです。それを行わなかった場合、関数はfalseとして返されます。例:isDerivedObject(function() {})はを返しますがfalse、今はを返しますtrue

  • オブジェクトとは何かの定義はいつでも変更できます。したがって、これらの関数を適宜変更できます。


テスト

function isObject(o) {
  return null != o && 
    typeof o === 'object' && 
    Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
  return !isObject(o) && 
    null != o && 
    (typeof o === 'object' || typeof o === 'function') &&
    /^\[object /.test(Object.prototype.toString.call(o));
}

// TESTS

// is null an object?

console.log(
  'is null an object?', isObject(null)
);

console.log(
  'is null a derived object?', isDerivedObject(null)
);

// is 1234 an object?

console.log(
  'is 1234 an object?', isObject(1234)
);

console.log(
  'is 1234 a derived object?', isDerivedObject(1234)
);

// is new Number(1234) an object?

console.log(
  'is new Number(1234) an object?', isObject(new Number(1234))
);

console.log(
  'is new Number(1234) a derived object?', isDerivedObject(1234)
);

// is function object an object?

console.log(
  'is (new (function (){})) an object?', 
  isObject((new (function (){})))
);

console.log(
  'is (new (function (){})) a derived object?', 
  isObject((new (function (){})))
);

// is {} an object?

console.log(
  'is {} an object?', isObject({})
);

console.log(
  'is {} a derived object?', isDerivedObject({})
);

// is Array an object?

console.log(
  'is Array an object?',
  isObject([])
)

console.log(
  'is Array a derived object?',
  isDerivedObject([])
)

// is Date an object?

console.log(
  'is Date an object?', isObject(new Date())
);

console.log(
  'is Date a derived object?', isDerivedObject(new Date())
);

// is function an object?

console.log(
  'is function an object?', isObject(function(){})
);

console.log(
  'is function a derived object?', isDerivedObject(function(){})
);


13

あなたがいるかどうかを確認したい場合prototypeのためにはobject、単にから来ていますObject。フィルタアウトStringNumberArrayArguments、など

function isObject (n) {
  return Object.prototype.toString.call(n) === '[object Object]';
}

または単一式の矢印関数として(ES6 +)

const isObject = n => Object.prototype.toString.call(n) === '[object Object]'

1
これが最善の方法ですが、私は2行目にすることによって、それより簡単になるだろう:return Object.prototype.toString.call(n) === '[object Object]'
mesqueeb

1
あなたも削除することができますnullので、チェックをObject.prototype.toString.call(null) === '[object Null]'
ガストバン・デ・ウォルマート

12
var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true

var b ={a: 1}
b instanceof Object //true
b instanceof Array //false

var c = null
c instanceof Object //false
c instanceof Array //false

詳細を尋ねられました。私たちの変数がオブジェクトであるかどうかをチェックのほとんどは、清潔で理解しやすい方法typeof myVar。これは、タイプ(例えば"object""undefined")の。

残念ながら、Arrayとnullのどちらにも型がありobjectます。実際のオブジェクトのみを取得するには、instanceof演算子を使用して継承チェーンをチェックする必要があります。nullは削除されますが、配列は継承チェーンにオブジェクトを持っています。

したがって、解決策は次のとおりです。

if (myVar instanceof Object && !(myVar instanceof Array)) {
  // code for objects
}

/./ instanceof Object //true
yckart 2017年

11

少し遅れて...「プレーンオブジェクト」(つまり、{'x':5、 'y':7}のように)には、次の小さなスニペットがあります。

function isPlainObject(o) {
   return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
           false
          :(typeof o == 'object');
}

次の出力が生成されます。

console.debug(isPlainObject(isPlainObject)); //function, false
console.debug(isPlainObject({'x': 6, 'y': 16})); //literal object, true
console.debug(isPlainObject(5)); //number, false
console.debug(isPlainObject(undefined)); //undefined, false
console.debug(isPlainObject(null)); //null, false
console.debug(isPlainObject('a')); //string, false
console.debug(isPlainObject([])); //array?, false
console.debug(isPlainObject(true)); //bool, false
console.debug(isPlainObject(false)); //bool, false

それはいつも私のために働きます。「o」のタイプが「オブジェクト」である場合にのみ「true」を返しますが、null、配列、または関数は返しません。:)


前の回答で述べたように、Dateオブジェクトの場合、アプローチは失敗します。
Grzegorz Pawlik 2017年

9

lodashにはisPlainObjectがあります。これは、このページにアクセスする多くの人が探しているものと思われます。関数または配列を指定するとfalseを返します。


パーフェクト!_.isObjectJSがオブジェクトと見なすものと一致するものは知っていました。しかし、私が通常必要とするのは、たとえばオブジェクトリテラルと配列を区別_.isPlainObjectすることです。これがまさに私にできることです。
ライム

9

これは機能します。これは、true、false、またはnullの可能性がある関数です。

const isObject = obj => obj && obj.constructor && obj.constructor === Object;

console.log(isObject({})); // true
console.log(isObject([])); // false
console.log(isObject(new Function)); // false
console.log(isObject(new Number(123))); // false
console.log(isObject(null)); // null


2
@SeregPie今後は、回答のコードを編集しないでください。この答えがnullそのままであるように、私がテストしたとき、私は最終テストの結果としてではなく、を得ましたfalseコードをいつ編集する必要があるかを
Nick

9

この問題を正しく処理する方法については多くの混乱があるように思われるので、2セント残しておきます(この回答は仕様に準拠しており、あらゆる状況で正しい結果を生成します)。

プリミティブのテスト: undefined null boolean string number

function isPrimitive(o){return typeof o!=='object'||null}

オブジェクトはプリミティブではありません:

function isObject(o){return !isPrimitive(o)}

または代わりに:

function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}

アレイのテスト:

const isArray=(function(){
    const arrayTypes=Object.create(null);
    arrayTypes['Array']=true;
    arrayTypes['Int8Array']=true;
    arrayTypes['Uint8Array']=true;
    arrayTypes['Uint8ClampedArray']=true;
    arrayTypes['Int16Array']=true;
    arrayTypes['Uint16Array']=true;
    arrayTypes['Int32Array']=true;
    arrayTypes['Uint32Array']=true;
    arrayTypes['BigInt64Array']=true;
    arrayTypes['BigUint64Array']=true;
    arrayTypes['Float32Array']=true;
    arrayTypes['Float64Array']=true;
    return function(o){
        if (!o) return false;
        return !isPrimitive(o)&&!!arrayTypes[o.constructor.name];
    }
}());

除外するオブジェクトのテスト:Date RegExp Boolean Number String Function任意の配列

const isObjectStrict=(function(){
    const nativeTypes=Object.create(null);
    nativeTypes['Date']=true;
    nativeTypes['RegExp']=true;
    nativeTypes['Boolean']=true;
    nativeTypes['Number']=true;
    nativeTypes['String']=true;
    nativeTypes['Function']=true;
    return function(o){
        if (!o) return false;
        return !isPrimitive(o)&&!isArray(o)&&!nativeTypes[o.constructor.name];
    }
}());

8

他のすべてが失敗した場合、私はこれを使用します:

var isObject = function(item) {
   return item.constructor.name === "Object";
}; 

1
なぜ文字列比較なのか、なぜ単純ではないのitem.constructor === Objectか?
K3 --- rnc 2016

null例外をスローするUncaught TypeError: Cannot read property 'constructor' of null(…)
Vitim.us

@rounce古いバージョンのIEをサポートすることを目指していますが、IEで動作しないのはなぜですか?以下のため、indexOfまたはのためにconstructor.name
Jankapunkt

8

RAMDA機能ライブラリは、JavaScriptの種類を検出するための素晴らしい機能を持っています。

完全な機能の言い換え:

function type(val) {
  return val === null      ? 'Null'      :
         val === undefined ? 'Undefined' :
         Object.prototype.toString.call(val).slice(8, -1);
}

ソリューションがいかにシンプルで美しいかを知ったとき、私は笑わなければなりませんでした。

Ramda ドキュメントの使用例:

R.type({}); //=> "Object"
R.type(1); //=> "Number"
R.type(false); //=> "Boolean"
R.type('s'); //=> "String"
R.type(null); //=> "Null"
R.type([]); //=> "Array"
R.type(/[A-z]/); //=> "RegExp"
R.type(() => {}); //=> "Function"
R.type(undefined); //=> "Undefined"

8

読書や実装の多くを試した後、私は非常に少数の人々のような値をチェックしてみていることに気づきましたJSONMathdocument 1つのステップよりも長いプロトタイプチェーンまたはオブジェクト。

typeof変数のをチェックしてからエッジケースをハッキングする代わりに、新しいプリミティブやネイティブオブジェクトが追加されたときにリファクタリングする必要がないように、チェックをできるだけ単純にした方が良いと思いましたtypeof 'object' '。

結局のところ、typeof演算子は何かがJavaScriptのオブジェクトであるかどうかを教えてくれますが、JavaScriptによるオブジェクトの定義は、ほとんどの実際のシナリオ(例typeof null === 'object')には広すぎます。以下は、v基本的に2つのチェックを繰り返すことにより、変数がオブジェクトかどうかを判断する関数です。

  1. ループは、限りの文字列化されたバージョンのように続けてその開始されvています'[object Object]'
    関数の結果が以下のログとまったく同じになるようにしたかったので、これが最終的な唯一の「オブジェクト性」基準です。失敗した場合、関数はすぐにfalseを返します。
  2. vチェーンの次のプロトタイプに置き換えられますが、その後v = Object.getPrototypeOf(v)も直接評価されます。vis の新しい値はnullルートプロトタイプ(チェーン内の唯一のプロトタイプである可能性が高い)を含むすべてのプロトタイプが、whileループのチェックに合格し、trueを返すことができることを意味します。それ以外の場合は、新しい反復が開始されます。

function isObj (v) {
  while (     Object.prototype.toString.call(v) === '[object Object]')
  if    ((v = Object.getPrototypeOf(v))         === null)
  return true
  return false
}

console.log('FALSE:')
console.log('[]                   -> ', isObj([]))
console.log('null                 -> ', isObj(null))
console.log('document             -> ', isObj(document))
console.log('JSON                 -> ', isObj(JSON))
console.log('function             -> ', isObj(function () {}))
console.log('new Date()           -> ', isObj(new Date()))
console.log('RegExp               -> ', isObj(/./))

console.log('TRUE:')
console.log('{}                   -> ', isObj({}))
console.log('new Object()         -> ', isObj(new Object()))
console.log('new Object(null)     -> ', isObj(new Object(null)))
console.log('new Object({})       -> ', isObj(new Object({foo: 'bar'})))
console.log('Object.prototype     -> ', isObj(Object.prototype))
console.log('Object.create(null)  -> ', isObj(Object.create(null)))
console.log('Object.create({})    -> ', isObj(Object.create({foo: 'bar'})))
console.log('deep inheritance     -> ', isObj(Object.create(Object.create({foo: 'bar'}))))


6
if(typeof value === 'object' && value.constructor === Object)
{
    console.log("This is an object");
}

1
これvaluenullエラーをスローしますか
Gershom

そしてもちろんそれはfalseオブジェクトのためになりますObject.assign({}, {constructor: null})
user4642212

6

指定された値がかどうかを明示的に確認する場合{}

function isObject (value) {
 return value && typeof value === 'object' && value.constructor === Object;
}

6
const isObject = function(obj) {
  const type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

!!objobj真実かどうかを確認するための省略形です(除外するためnull


6

古い質問ですが、ここに残しておくと考えられました。ほとんどの人は、変数が{}キーと値のペアを意味しているかどうかをチェックしていますが、JavaScriptが特定の目的で使用している下線の構成ではありません。正直に言うと、JavaScriptのほとんどすべてがオブジェクトです。だから、邪魔にならないように。もしあなたがそうするなら...

let x = function() {}
typeof x === 'function' //true
x === Object(x) // true
x = []
x === Object(x) // true

// also
x = null
typeof null // 'object'

ほとんどの場合、必要なのは、APIからのリソースオブジェクトがあるのか​​、ORMから返されたデータベース呼び出しがあるのか​​を知ることです。次にArray、が、でないnull、typeof 'function'でなく、であるかどうかをテストできますObject

// To account also for new Date() as @toddmo pointed out

x instanceof Object && x.constructor === Object

x = 'test' // false
x = 3 // false
x = 45.6 // false
x = undefiend // false
x = 'undefiend' // false
x = null // false
x = function(){} // false
x = [1, 2] // false
x = new Date() // false
x = {} // true

ポップtrueのためにnew Date()
toddmo

1
@toddmo指摘してくれてありがとう。今のコード例では、のために偽を返すnew Date()
ギルバート

4

私が使いたいのはこれ

function isObject (obj) {
  return typeof(obj) == "object" 
        && !Array.isArray(obj) 
        && obj != null 
        && obj != ""
        && !(obj instanceof String)  }

ほとんどの場合、日付はチェックをオブジェクトとして渡す必要があるので、日付を除外しません


4

私はこのSOの質問からこの種の型チェックだけを行う「新しい」方法を見つけました:一部のリテラルでinstanceofがfalseを返すのはなぜですか?

それから、次のように型チェック用の関数を作成しました:

function isVarTypeOf(_var, _type){
    try {
        return _var.constructor === _type;
    } catch(ex) {
        return false;         //fallback for null or undefined
    }
}

その後、あなたはただ行うことができます:

console.log(isVarTypeOf('asdf', String));   // returns true
console.log(isVarTypeOf(new String('asdf'), String));   // returns true
console.log(isVarTypeOf(123, String));   // returns false
console.log(isVarTypeOf(123, Number));   // returns true
console.log(isVarTypeOf(new Date(), String));   // returns false
console.log(isVarTypeOf(new Date(), Number));   // returns false
console.log(isVarTypeOf(new Date(), Date));   // returns true
console.log(isVarTypeOf([], Object));   // returns false
console.log(isVarTypeOf([], Array));   // returns true
console.log(isVarTypeOf({}, Object));   // returns true
console.log(isVarTypeOf({}, Array));   // returns false
console.log(isVarTypeOf(null, Object));   // returns false
console.log(isVarTypeOf(undefined, Object));   // returns false
console.log(isVarTypeOf(false, Boolean));   // returns true

これはChrome 56、Firefox 52、Microsoft Edge 38、Internet Explorer 11、Opera 43でテストされています

編集:
変数がnullまたは未定義かどうかも確認する場合は、代わりにこれを使用できます。

function isVarTypeOf(_var, _type){
    try {
        return _var.constructor === _type;
    } catch(ex) {
        return _var == _type;   //null and undefined are considered the same
        // or you can use === if you want to differentiate them
    }
}

var a = undefined, b = null;
console.log(isVarTypeOf(a, undefined)) // returns true
console.log(isVarTypeOf(b, undefined)) // returns true
console.log(isVarTypeOf(a, null)) // returns true

inancのコメントからの更新:チャレンジが受け入れられました:D

比較オブジェクトを緩めたい場合は、次の方法を試すことができます。

function isVarTypeOf(_var, _type, looseCompare){
    if (!looseCompare){
        try {
            return _var.constructor === _type;
        } catch(ex){
            return _var == _type;
        }
    } else {
        try{
            switch(_var.constructor){
                case Number:
                case Function:
                case Boolean:
                case Symbol:
                case Date:
                case String:
                case RegExp:
                    // add all standard objects you want to differentiate here
                    return _var.constructor === _type;
                case Error:
                case EvalError:
                case RangeError:
                case ReferenceError:
                case SyntaxError:
                case TypeError:
                case URIError:
                    // all errors are considered the same when compared to generic Error
                    return (_type === Error ? Error : _var.constructor) === _type;
                case Array:
                case Int8Array:
                case Uint8Array:
                case Uint8ClampedArray:
                case Int16Array:
                case Uint16Array:
                case Int32Array:
                case Uint32Array:
                case Float32Array:
                case Float64Array:
                    // all types of array are considered the same when compared to generic Array
                    return (_type === Array ? Array : _var.constructor) === _type;
                case Object:
                default:
                    // the remaining are considered as custom class/object, so treat it as object when compared to generic Object
                    return (_type === Object ? Object : _var.constructor) === _type;
            }
        } catch(ex){
            return _var == _type;   //null and undefined are considered the same
            // or you can use === if you want to differentiate them
        }
    }
}

そうすれば、inancのコメントと同じようにできます。

isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true

または

Foo = function(){};
Bar = function(){};
isVarTypeOf(new Foo(), Object);   // returns false
isVarTypeOf(new Foo(), Object, true);   // returns true
isVarTypeOf(new Bar(), Foo, true);   // returns false
isVarTypeOf(new Bar(), Bar, true);   // returns true
isVarTypeOf(new Bar(), Bar);    // returns true

これは、新しいクラスがオブジェクトであるかどうかを検出できません。isVarTypeOf(new(function Foo(){})、Object)//これは、trueではなくfalseを返します。適切なチェックについては、以下の私の答えを参照してください。
イナングムス

ただし、を使用instanceofしてオブジェクトを確認できます。それでも、これは正確な科学ではありません。
イナンクムス

ためであるだけでなく@inanc、new Foo()戻りFooオブジェクト、同じnew String()戻りStringオブジェクト、またはnew Date()返すDateオブジェクトは、あなたができることFoo = function(){}; isVarTypeOf(new Foo(), Foo);
am05mhz

ええ、それは私が実際に言っていることです。あなたはそれが現在オブジェクトであるかどうかをチェックしていません。
イナンクムス

@inanc乾杯、私は型チェック(オブジェクトだけでなく)を行う方法を探していて、このページと他のページに行きました、そして私はこの質問のコンテキストを忘れてしまったので興奮しました、私の悪い:)
am05mhz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.