値がJavaScriptのオブジェクトであるかどうかをどのように確認しますか?
値がJavaScriptのオブジェクトであるかどうかをどのように確認しますか?
回答:
更新:
この答えは不完全であり、誤解を招く結果になります。たとえば、他のいくつかのエッジケースは言うまでもなく、JavaScript null
のタイプとも見なさobject
れます。以下の推奨事項に従って、他の「最も賛成された(そして正しい!)回答」に進んでください。
元の答え:
typeof(var)
またはを使用してみてくださいvar instanceof something
。
編集:この回答は変数のプロパティを調べる方法のアイデアを提供しますが、それが遠く離れたオブジェクトであるかどうかをチェックするための完全なレシピではありません(結局、レシピはまったくありません!)。人々は調査を行わずにここからコピーするものを探す傾向があるため、他の最も賛成された(そして正しい!)答えに目を向けることを強くお勧めします。
typeof
は演算子なので、は必要ありません()
。
typeof
オブジェクトではないnullに対して 'object'を返し、をinstanceof
使用して作成されたオブジェクトに対しては機能しませんObject.create(null)
。
の場合typeof yourVariable === 'object'
、それはオブジェクトまたはnullです。nullを除外する場合は、単にnullにしますtypeof yourVariable === 'object' && yourVariable !== null
。
yourVariable !== null
、より良い練習になりますか?
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.
typeof
には、十分に理解できるとは限らないいくつかの特殊なケースがあるため、詳細を確認する必要があります。配列と配列ではないオブジェクトを区別しようとしている場合は、絶対にを使用しないでくださいtypeof
。
Object.prototype.toString.call(yourVar)
があるのはyourVarです。配列の場合、Object.prototype.toString.call([1,2])
戻り値[object Array]
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({})
obj === Object(obj)
true
配列を返します。
var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
たとえば、オブジェクトであるがスローされる、取り消されたプロキシでは機能しません。
({}).toString.apply(obj) === '[object Object]'
これが配列と配列ではないオブジェクトを区別しないのはなぜですか
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;
};
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
null
ます。受け入れられる答えでなければなりません。
Object.prototype.toString.call(myVar)
戻ります:
"[object Object]"
myVarがオブジェクトの場合"[object Array]"
myVarが配列の場合これの詳細と、typeofの代わりに使用できる理由については、こちらの記事をご覧ください。
typeof [] === 'object'
-> true
。これがこのメソッドに必要なものです。
Object.prototype.toString.call(3)
-> "[object Number]"
。Object.prototype.toString.call(new Number(3))
-> "[object Number]
"
getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
追加の関数呼び出し(速度)なしで単純にオブジェクトまたは配列をチェックします。こちらにも掲載しています。
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
{
文字で始まるものとして表されますか?配列の場合、IE <9をサポートする必要がない限り、を使用Array.isArray()
して、何かが配列かどうかを判断できます。あなたが提供したすべてのテストケースに合格します。
私は単純に好きです:
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
new Date()
オブジェクトを返すため。配列はオブジェクトではなく論理的な観点からのものです-JavaScriptはそれらをそのように処理して報告します。しかし実際には、それらが等しくないので、それらを等しく見ることは役に立ちません。length
たとえば、オブジェクトには属性がなく、push()などのメソッドもありません。また、関数またはオーバーロードされたパラメーターを指定したい場合があります。特に、他のパラメーターが指定されたパラメーターに依存している場合は、配列またはオブジェクトを区別する必要があります。
length
ようなプロパティやメソッドをpush
、Object.create(Array.prototype)
これらを持っている非配列オブジェクトの些細な反例です。配列が特別なのは、配列がカスタム[[DefineOwnProperty]]必須の内部メソッドを持つエキゾチックなオブジェクトであるということですが、それでもオブジェクトです。
length
プロパティを設定できないことも書きませんでした(オブジェクトリテラルにはlength
デフォルトで属性がないことを意味します)。配列は論理的な観点からのオブジェクトではないことを書きました。私はプログラムロジックについて話している。配列が「実際の」配列であり、「実際の」オブジェクトではないことを確認する必要がある場合があります。それArray.isArray()
が目的です。オブジェクトまたはオブジェクトの配列を受け入れる関数があるとします。特別な属性またはメソッドをチェックすることは、汚い解決策です。ネイティブの方法は常に優れています。
typeof null
は"object"
、ではありません"undefined"
。
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
その結果、厳格で堅牢なコードが作成されます。
、、などの関数を作成しない場合isDate
はisError
、isRegExp
この一般化された関数を使用するオプションを検討できます。
function isObject(o) {
return o instanceof Object && typeof o.constructor === 'function';
}
前述のすべてのテストケースでは正しく機能しませんが、(プレーンまたは構築された)すべてのオブジェクトに対しては十分です。
isObject
Object.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にはすでにパッケージが作成されています!そして、それは前述のすべてのテストケースで機能します!🙂
isDate
堅牢なコードを書く目的でyourDateObject に使用しなければなりませんisObject
。そうでなければ、もろいメソッドがあります。
Date
はい、答えは議論してDate
いるので、私のコメントでのは不適切な選択でした。しかし、これDate
は無限の可能なクラスの1つにすぎず、他のクラスについても同じことが言えます。例:をclass Foo() { }; var x = new Foo(); isObject(x)
返しますfalse
。OPのユースケースは正確にはわかりませんが、考えられるすべてのクラスについて知っている必要があり、クラスごとに具体的にチェックすることが実行不可能になるシナリオは簡単に想像できます。
何てことだ!これはこれまでよりも短くなると思います、これを見てみましょう:
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
関数または"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
Object.create(null)
、そしてとにかくなぜそうするのか...?
質問に答える前に、まずこの概念を説明しましょう。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);
これは、「オブジェクトである」という意味によって異なります。プリミティブではないすべてのもの、つまり新しいプロパティを設定できるものが必要な場合は、これでうまくいくはずです。
function isAnyObject(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
プリミティブ(プレーンな数値/ NaN
/ Infinity
、プレーンな文字列、シンボル、true
/ false
、undefined
および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でのプレーンオブジェクトの定義がさらに複雑になっています。
instanceof Object
など、二つの同一の関数リテラルは厳密に等しくない、それらは参照によって渡され、
私の神様、他の答えに混乱が多すぎます。
簡潔な答え
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で配列をチェックする方法をすでに学習している可能性があります。
false
場合anyVar
は(必要に応じて)も返すことです。
値の型をチェックする最も合理的な方法は、typeof
演算子のようです。唯一の問題は、ひどく壊れていることです。
"object"
ためにnull
Null型に属する。"function"
、オブジェクトタイプに属する呼び出し可能なオブジェクトに対して。"unknown"
です。禁止されている結果は"function"
、プリミティブ型のみです。typeof
非null
プリミティブに対してのみ信頼できます。したがって、値がオブジェクトであるかどうかを確認する方法は、によって返される文字列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.create
とObject.getPrototypeOf
ECMAScriptの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
直接アクセスすることなく参照するだけです。
これを試して
if (objectName instanceof Object == false) {
alert('Not an object');
}
else {
alert('An object');
}
Object.prototype instanceof Object
ます:-> false。 Object.create(null) instanceof Object
-> false。
new Date() instanceof Object
=> 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));
}
// 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では、null
、Object
、Array
、Date
およびfunction
Sは、すべてのオブジェクトです。しかし、null
少し工夫されています。したがって、null
最初のものをチェックして、それがnullではないことを検出することをお勧めします。
オブジェクトであるtypeof o === 'object'
保証のチェックo
。このチェックがなければ、Object.prototype.toString
それもために、everthingのためのオブジェクトを返しますから、意味がないundefined
とnull
!次に例を示しtoString(undefined)
ます。[object Undefined]
。
typeof o === 'object'
チェック後、toString.call(o)o
は、オブジェクト、のような派生オブジェクトArray
、Date
またはであるかどうかをチェックするのに最適なメソッド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(){})
);
あなたがいるかどうかを確認したい場合prototype
のためにはobject
、単にから来ていますObject
。フィルタアウトString
、Number
、Array
、Arguments
、など
function isObject (n) {
return Object.prototype.toString.call(n) === '[object Object]';
}
または単一式の矢印関数として(ES6 +)
const isObject = n => Object.prototype.toString.call(n) === '[object Object]'
return Object.prototype.toString.call(n) === '[object Object]'
null
ので、チェックをObject.prototype.toString.call(null) === '[object Null]'
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
少し遅れて...「プレーンオブジェクト」(つまり、{'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、配列、または関数は返しません。:)
lodashにはisPlainObjectがあります。これは、このページにアクセスする多くの人が探しているものと思われます。関数または配列を指定するとfalseを返します。
_.isObject
JSがオブジェクトと見なすものと一致するものは知っていました。しかし、私が通常必要とするのは、たとえばオブジェクトリテラルと配列を区別_.isPlainObject
することです。これがまさに私にできることです。
これは機能します。これは、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
null
そのままであるように、私がテストしたとき、私は最終テストの結果としてではなく、を得ましたfalse
。コードをいつ編集する必要があるかを
この問題を正しく処理する方法については多くの混乱があるように思われるので、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];
}
}());
他のすべてが失敗した場合、私はこれを使用します:
var isObject = function(item) {
return item.constructor.name === "Object";
};
item.constructor === Object
か?
null
例外をスローするUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
またはのためにconstructor.name
?
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"
読書や実装の多くを試した後、私は非常に少数の人々のような値をチェックしてみていることに気づきましたJSON
、Math
、document
1つのステップよりも長いプロトタイプチェーンまたはオブジェクト。
typeof
変数のをチェックしてからエッジケースをハッキングする代わりに、新しいプリミティブやネイティブオブジェクトが追加されたときにリファクタリングする必要がないように、チェックをできるだけ単純にした方が良いと思いましたtypeof
'object' '。
結局のところ、typeof
演算子は何かがJavaScriptのオブジェクトであるかどうかを教えてくれますが、JavaScriptによるオブジェクトの定義は、ほとんどの実際のシナリオ(例typeof null === 'object'
)には広すぎます。以下は、v
基本的に2つのチェックを繰り返すことにより、変数がオブジェクトかどうかを判断する関数です。
v
ています'[object Object]'
。v
チェーンの次のプロトタイプに置き換えられますが、その後v = Object.getPrototypeOf(v)
も直接評価されます。v
is の新しい値は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'}))))
if(typeof value === 'object' && value.constructor === Object)
{
console.log("This is an object");
}
value
はnull
エラーをスローしますか
false
オブジェクトのためになりますObject.assign({}, {constructor: null})
。
古い質問ですが、ここに残しておくと考えられました。ほとんどの人は、変数が{}
キーと値のペアを意味しているかどうかをチェックしていますが、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()
new Date()
私はこの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
instanceof
してオブジェクトを確認できます。それでも、これは正確な科学ではありません。
new Foo()
戻りFoo
オブジェクト、同じnew String()
戻りString
オブジェクト、またはnew Date()
返すDate
オブジェクトは、あなたができることFoo = function(){}; isVarTypeOf(new Foo(), Foo);
も
null
があります(オブジェクトであるかどうかなど)。