Wie überprüfen Sie, ob ein Wert ein Objekt in JavaScript ist?
Wie überprüfen Sie, ob ein Wert ein Objekt in JavaScript ist?
Antworten:
UPDATE :
Diese Antwort ist unvollständig und führt zu irreführenden Ergebnissen . Wird beispielsweise null
auch object
in JavaScript als Typ betrachtet , ganz zu schweigen von einigen anderen Randfällen. Befolgen Sie die unten stehende Empfehlung und fahren Sie mit der anderen "am besten bewerteten (und richtigen!) Antwort" fort .
Ursprüngliche Antwort :
Versuchen Sie es mit typeof(var)
und / oder var instanceof something
.
BEARBEITEN: Diese Antwort gibt eine Vorstellung davon, wie die Eigenschaften von Variablen untersucht werden können, ist jedoch kein kugelsicheres Rezept (schließlich gibt es überhaupt kein Rezept!), Um zu überprüfen, ob es sich um ein Objekt handelt, das weit davon entfernt ist. Da die Leute dazu neigen, nach etwas zu suchen, das sie von hier kopieren können, ohne Nachforschungen anzustellen, würde ich dringend empfehlen, dass sie sich der anderen, am besten bewerteten (und korrektesten!) Antwort zuwenden.
typeof
ist ein Operator, also keine Notwendigkeit für ()
.
typeof
Gibt 'Objekt' für null zurück, das kein Objekt ist, und instanceof
funktioniert nicht für Objekte, die mit erstellt wurden Object.create(null)
.
Wenn typeof yourVariable === 'object'
, ist es ein Objekt oder null. Wenn Sie null ausschließen möchten, machen Sie es einfach typeof yourVariable === 'object' && yourVariable !== null
.
yourVariable !== null
eine bessere Praxis?
typeof null == 'object'
dies in ES6 nicht behoben wird . Sie sagten: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
da es einige Sonderfälle gibt, die nicht unbedingt viel Sinn ergeben. Wenn Sie versuchen, zwischen Arrays und Objekten zu unterscheiden, die keine Arrays sind, möchten Sie diese definitiv nicht verwenden typeof
.
Object.prototype.toString.call(yourVar)
, da du dein Var bist, was du inspizieren musst. Im Falle von Arrays, Object.prototype.toString.call([1,2])
kehrt[object Array]
Definieren wir "Objekt" in Javascript . Gemäß den MDN-Dokumenten ist jeder Wert entweder ein Objekt oder ein Grundelement:
primitiver, primitiver Wert
Daten, die kein Objekt sind und keine Methoden haben. JavaScript hat 5 primitive Datentypen: Zeichenfolge, Zahl, Boolescher Wert, Null, undefiniert.
Was ist ein Primitiv?
3
'abc'
true
null
undefined
Was ist ein Objekt (dh kein Primitiv)?
Object.prototype
Object.prototype
Function.prototype
Object
Function
function C(){}
- benutzerdefinierte FunktionenC.prototype
- die Prototyp-Eigenschaft einer benutzerdefinierten Funktion: Dies ist kein C
Prototyp
new C()
- "Neu" - eine benutzerdefinierte FunktionMath
Array.prototype
{"a": 1, "b": 2}
- Objekte, die in Literalschreibweise erstellt wurdennew Number(3)
- Umhüllungen von GrundelementenObject.create(null)
Object.create(null)
So überprüfen Sie, ob ein Wert ein Objekt ist
instanceof
an sich wird nicht funktionieren, weil es zwei Fälle übersieht:
// oops: isObject(Object.prototype) -> false
// oops: isObject(Object.create(null)) -> false
function isObject(val) {
return val instanceof Object;
}
typeof x === 'object'
funktioniert wegen falsch positiver ( null
) und falsch negativer (Funktionen) nicht:
// oops: isObject(Object) -> false
function isObject(val) {
return (typeof val === 'object');
}
Object.prototype.toString.call
funktioniert nicht, weil für alle Grundelemente falsch positive Ergebnisse vorliegen:
> Object.prototype.toString.call(3)
"[object Number]"
> Object.prototype.toString.call(new Number(3))
"[object Number]"
Also benutze ich:
function isObject(val) {
if (val === null) { return false;}
return ( (typeof val === 'function') || (typeof val === 'object') );
}
@ Daans Antwort scheint auch zu funktionieren:
function isObject(obj) {
return obj === Object(obj);
}
weil laut MDN-Dokumenten :
Der Objektkonstruktor erstellt einen Objekt-Wrapper für den angegebenen Wert. Wenn der Wert null oder undefiniert ist, wird ein leeres Objekt erstellt und zurückgegeben. Andernfalls wird ein Objekt eines Typs zurückgegeben, der dem angegebenen Wert entspricht. Wenn der Wert bereits ein Objekt ist, wird der Wert zurückgegeben.
Eine dritte Möglichkeit, die Arbeit scheint (nicht sicher , ob es 100%) verwendet wird , Object.getPrototypeOf
die eine Ausnahme auslöst , wenn ihr Argument nicht ein Objekt ist:
// 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)
Gibt true
für Arrays zurück.
var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
funktioniert zB nicht mit widerrufenen Proxys, die Objekte sind, aber werfen.
({}).toString.apply(obj) === '[object Object]'
unterscheidet dies zwischen Arrays und Objekten, die keine Arrays sind
underscore.js bietet die folgende Methode, um herauszufinden, ob etwas wirklich ein Objekt ist:
_.isObject = function(obj) {
return obj === Object(obj);
};
AKTUALISIEREN
Aufgrund eines früheren Fehlers in V8 und einer geringfügigen Optimierung der Mikrogeschwindigkeit sieht die Methode seit underscore.js 1.7.0 (August 2014) wie folgt aus :
_.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
auch. Sollte die akzeptierte Antwort sein.
Object.prototype.toString.call(myVar)
wird zurückkehren:
"[object Object]"
wenn myVar ein Objekt ist"[object Array]"
wenn myVar ein Array istWeitere Informationen dazu und warum es eine gute Alternative zu typeof ist, finden Sie in diesem Artikel .
typeof [] === 'object'
-> true
. Das ist es, was Sie diese Methode brauchen.
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];};
Zum einfachen Prüfen gegen Objekt oder Array ohne zusätzlichen Funktionsaufruf (Geschwindigkeit). Wie auch hier gepostet .
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 () - Hinweis: Nur für Objektliterale verwenden, da für benutzerdefinierte Objekte wie new Date oder new YourCustomObject false zurückgegeben wird.
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
funktioniert nur mit Objektliteralen. Wenn ich einen benutzerdefinierten Typ erstelle, eine Instanz des Typs erstelle und ihn false
Boolean(a)
ist länger, aber weitaus intuitiver. Verwenden Sie einfach nicht new Boolean(a)
: ( hier ist der Grund )!
{
Zeichen beginnt . Für den Array-Fall können Sie verwenden, Array.isArray()
um festzustellen, ob es sich bei einem Array um ein Array handelt , solange Sie IE <9 nicht unterstützen müssen . Es besteht alle von Ihnen bereitgestellten Testfälle.
Ich mag einfach:
function isObject (item) {
return (typeof item === "object" && !Array.isArray(item) && item !== null);
}
Wenn es sich bei dem Element um ein JS-Objekt handelt und es sich nicht um ein JS-Array handelt und nicht null
... Wenn sich alle drei als wahr erweisen, kehren Sie zurück true
. Wenn eine der drei Bedingungen fehlschlägt, wird der &&
Test kurzgeschlossen und false
zurückgegeben. Der null
Test kann bei Bedarf weggelassen werden (je nachdem, wie Sie ihn verwenden null
).
DOKUMENTE:
http://devdocs.io/javascript/operators/typeof
http://devdocs.io/javascript/global_objects/object
new Date()
ein Objekt zurückgegeben wird. Ein Array ist aus logischer Sicht kein Objekt - obwohl JavaScript sie als solche behandelt und meldet. In der Praxis ist es jedoch nicht hilfreich, sie gleich zu sehen, weil sie es nicht sind. Ein Objekt hat length
zum Beispiel kein Attribut und keine Methoden wie push (). Und manchmal möchten Sie einer Funktion überladene Parameter geben, bei denen Sie einen Unterschied zwischen einem Array oder einem Objekt machen müssen, insbesondere wenn andere Parameter davon abhängen, welcher angegeben wurde.
length
Eigenschaft oder Methoden wie haben können push
, Object.create(Array.prototype)
ist ein triviales Gegenbeispiel für ein Nicht-Array-Objekt, das diese hat. Das Besondere an Arrays ist, dass es sich um exotische Objekte mit einer benutzerdefinierten [[DefineOwnProperty]] wesentlichen internen Methode handelt, die jedoch weiterhin Objekte sind.
length
Eigenschaft haben können (ich meinte, dass Objektliterale length
standardmäßig kein Attribut haben). Ich habe geschrieben, dass Arrays aus logischer Sicht keine Objekte sind . Ich spreche von Programmlogik. Manchmal muss überprüft werden, ob ein Array ein "echtes" Array und definitiv kein "echtes" Objekt ist. Dafür Array.isArray()
ist es da. Stellen Sie sich vor, Sie haben eine Funktion, die ein Objekt oder ein Array von Objekten akzeptiert. Das Überprüfen auf ein spezielles Attribut oder eine spezielle Methode ist eine schmutzige Lösung. Der native Weg ist immer besser.
typeof null
ist "object"
nicht "undefined"
.
Array.isArray
:function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}
Array.isArray
:Nur überrascht, wie viele Upvotes für falsche Antworten 😮
Nur 1 Antwort hat meine Tests bestanden !!! Hier habe ich meine vereinfachte Version erstellt:
function isObject(o) {
return o instanceof Object && o.constructor === Object;
}
Was mich betrifft, ist es klar und einfach und funktioniert einfach! Hier meine Tests:
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
EINMAL MEHR: Nicht alle Antworten bestehen diese Tests !!! 🙈
Wenn Sie überprüfen müssen, ob das Objekt eine Instanz einer bestimmten Klasse ist , müssen Sie den Konstruktor mit Ihrer bestimmten Klasse überprüfen, z.
function isDate(o) {
return o instanceof Object && o.constructor === Date;
}
einfacher Test:
var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d)); // Will return: true
Als Ergebnis erhalten Sie strengen und robusten Code!
Für den Fall , werden Sie nicht schaffen Funktionen wie isDate
, isError
, isRegExp
usw. Sie Option in Betracht ziehen kann dieser verallgemeinerten Funktionen zu nutzen:
function isObject(o) {
return o instanceof Object && typeof o.constructor === 'function';
}
Es funktioniert nicht für alle zuvor erwähnten Testfälle richtig, aber es ist gut genug für alle Objekte (einfach oder konstruiert).
isObject
funktioniert nicht, wenn die Object.create(null)
interne Implementierung hierObject.create
erläutert wird , aber Sie können sie isObject
in einer komplexeren Implementierung verwenden:
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;
};
Basierend auf dieser Implementierung wurde bereits ein Paket auf npm v1 erstellt! Und es funktioniert für alle zuvor beschriebenen Testfälle! 🙂
isDate
für Ihr DateObject den Zweck verwenden, robusten Code zu schreiben, sonst haben Sie eine spröde isObject
Methode.
Date
in meinem Kommentar wurde schlecht gewählt, weil ja, die Antwort diskutiert Date
. Ist Date
aber nur eine von unendlich möglichen Klassen und der Punkt gilt für jede andere Klasse. Beispiel: gibt class Foo() { }; var x = new Foo(); isObject(x)
zurück false
. Ich weiß nicht genau, was der Anwendungsfall des OP ist, aber es ist einfach, sich Szenarien vorzustellen, in denen es unmöglich sein wird , über alle möglichen Klassen Bescheid zu wissen und spezifisch gegen jede einzelne zu prüfen.
Oh mein Gott! Ich denke, das könnte kürzer sein als je zuvor. Sehen wir uns das an:
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
Typ von JavaScript-Objekten (einschließlich null
) gibt zurück"object"
console.log(typeof null, typeof [], typeof {})
Das Überprüfen ihrer constructor
Eigenschaft gibt die Funktion mit ihren Namen zurück.
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
Gibt einen schreibgeschützten Namen einer Funktion oder "anonymous"
für Schließungen zurück.
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
Hinweis: Ab 2018 funktioniert Function.name möglicherweise nicht mehr im IE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility
Object.create(null)
und warum würdest du das überhaupt tun ...?
OK, lassen Sie uns dieses Konzept zuerst geben, bevor Sie Ihre Frage beantworten. In JavaScript sind die Funktionen Objekt, auch Null, Objekt, Arrays und sogar Datum. Wie Sie sehen, gibt es also keinen einfachen Weg wie typeof obj === 'object' Alles, was oben erwähnt wurde, gibt true zurück , aber es gibt Möglichkeiten, dies durch Schreiben einer Funktion oder Verwenden von JavaScript-Frameworks zu überprüfen. OK:
Stellen Sie sich nun vor, Sie haben dieses Objekt, das ein reales Objekt ist (nicht null oder Funktion oder Array):
var obj = {obj1: 'obj1', obj2: 'obj2'};
Reines JavaScript:
//that's how it gets checked in angular framework
function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
oder
//make sure the second object is capitalised
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
oder
function isObject(obj) {
return obj.constructor.toString().indexOf("Object") > -1;
}
oder
function isObject(obj) {
return obj instanceof Object;
}
Sie können einfach eine dieser Funktionen wie oben in Ihrem Code verwenden, indem Sie sie aufrufen. Wenn es sich um ein Objekt handelt, wird true zurückgegeben:
isObject(obj);
Wenn Sie ein JavaScript-Framework verwenden, haben diese normalerweise diese Art von Funktionen für Sie vorbereitet. Dies sind nur einige davon:
jQuery:
//It returns 'object' if real Object;
jQuery.type(obj);
Winkel:
angular.isObject(obj);
Unterstrich und Lodash:
//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);
Es kommt darauf an, was du mit "ist ein Objekt" meinst. Wenn Sie alles wollen, was nicht primitiv ist , dh Dinge, für die Sie neue Eigenschaften festlegen können, sollte dies den Trick tun:
function isAnyObject(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
Ausgeschlossen sind die Grundelemente (ganze Zahlen / NaN
/ Infinity
, blanke Saiten, Symbole, true
/ false
, undefined
und null
) sollte aber für alles andere true zurück (einschließlich Number
, Boolean
und String
Objekte). Beachten Sie, dass JS nicht definiert, welche "Host" -Objekte, wie z. B. window
oder console
, bei Verwendung mit zurückgegeben werden sollen typeof
, sodass diese mit einer solchen Prüfung nur schwer abgedeckt werden können.
Wenn Sie wissen möchten, ob etwas ein "einfaches" Objekt ist, dh es wurde als Literal {}
oder mit erstellt Object.create(null)
, können Sie Folgendes tun:
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;
}
}
Bearbeiten 2018 : Da Symbol.toStringTag
jetzt das Anpassen der Ausgabe von möglich ist Object.prototype.toString.call(...)
, kann die isPlainObject
obige Funktion false
in einigen Fällen zurückgegeben werden, selbst wenn das Objekt sein Leben als Literal begann. Konventionell ist ein Objekt mit einem benutzerdefinierten String-Tag wohl kein einfaches Objekt mehr, aber dies hat die Definition dessen, was ein einfaches Objekt überhaupt in Javascript ist, weiter getrübt.
instanceof Object
, zwei identische Funktionsliterale sind nicht streng gleich, sie werden als Referenz übergeben usw.
Mein Gott, zu viel Verwirrung in anderen Antworten.
Kurze Antwort
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)
Um dies zu testen, führen Sie einfach die folgenden Anweisungen in der Chrome-Konsole aus.
Fall 1.
var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true
Fall 2.
anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false
Fall 3.
anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false
Erläuterung
Okay. Lass es uns zusammenfassen
typeof anyVar == 'object'
wird von drei Kandidaten als wahr zurückgegeben - [], {} and null
,
anyVar instanceof Object
schränkt diese Kandidaten auf zwei ein - [], {}
!(anyVar instanceof Array)
verengt sich auf nur einen - {}
Trommelwirbel bitte!
Auf diese Weise haben Sie möglicherweise bereits gelernt, wie Sie in Javascript nach Arrays suchen.
false
(wie gewünscht) zurückgegeben wird, wenn anyVar
es sich um eine Funktion handelt.
Der vernünftigste Weg, den Typ eines Wertes zu überprüfen, scheint der typeof
Operator zu sein. Das einzige Problem ist, dass es schrecklich kaputt ist:
"object"
für zurückgegeben null
, was zum Typ Null gehört."function"
für aufrufbare Objekte zurückgegeben, die zum Objekttyp gehören."unknown"
. Die einzigen verbotenen Ergebnisse sind "function"
primitive Typen.typeof
ist nur für Nichtprimitive zuverlässig null
. Eine Möglichkeit, um zu überprüfen, ob ein Wert ein Objekt ist, besteht darin, sicherzustellen, dass die von zurückgegebene Zeichenfolge typeof
keinem Grundelement entspricht und das Objekt nicht null
. Das Problem ist jedoch, dass ein zukünftiger Standard einen neuen primitiven Typ einführen könnte, und unser Code würde ihn als Objekt betrachten. Neue Typen werden nicht häufig angezeigt, aber beispielsweise hat ECMAScript 6 den Symboltyp eingeführt.
Daher typeof
empfehle ich stattdessen nur Ansätze, deren Ergebnis davon abhängt, ob der Wert ein Objekt ist oder nicht. Das Folgende soll ein sein
Object
Konstrukteur
Der Object
Konstruktor erzwingt das übergebene Argument für ein Objekt. Wenn es sich bereits um ein Objekt handelt, wird dasselbe Objekt zurückgegeben.
Daher können Sie damit den Wert eines Objekts erzwingen und dieses Objekt streng mit dem ursprünglichen Wert vergleichen.
Die folgende Funktion erfordert ECMAScript 3, das eingeführt wurde ===
:
function isObject(value) { /* Requires ECMAScript 3 or later */
return Object(value) === value;
}
Ich mag diesen Ansatz, weil er einfach und selbstbeschreibend ist und eine analoge Prüfung auch für Boolesche Werte, Zahlen und Zeichenfolgen funktioniert. Beachten Sie jedoch, dass das Globale Object
weder beschattet noch verändert wird.
Konstruktoren
Wenn Sie einen Konstruktor instanziieren, kann er einen anderen Wert als die gerade erstellte Instanz zurückgeben. Dieser Wert wird jedoch ignoriert, es sei denn, es handelt sich um ein Objekt.
Die folgende Funktion erfordert ECMAScript 3, mit dem Konstruktoren Nichtobjekte zurückgeben können. Vor ECMAScript 3 gab es einen Fehler, aber try
Anweisungen gab es damals noch nicht.
function isObject(value) { /* Requires ECMAScript 3 or later */
return new function() { return value; }() === value;
}
Dieses Beispiel ist zwar etwas weniger einfach als das vorherige, es basiert jedoch nicht auf einer globalen Eigenschaft und ist daher möglicherweise die sicherste.
this
Wert
Bei alten ECMAScript-Spezifikationen musste der this
Wert ein Objekt sein. Einführung von ECMAScript 3 Function.prototype.call
, mit dem eine beliebige Funktion aufgerufen werden konntethis
Wert , aber zu einem Objekt gezwungen werden konnte.
ECMAScript 5 führte einen strengen Modus ein, der dieses Verhalten beseitigte, aber im schlampigen Modus können wir uns immer noch darauf verlassen (sollten es aber wohl nicht).
function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
return function() { return this === value; }.call(value);
}
[[Prototyp]]
Alle gewöhnlichen Objekte haben einen internen Steckplatz namens [[Prototype]], dessen Wert bestimmt, von welchem anderen Objekt sie erben. Der Wert kann nur ein Objekt sein oder null
. Daher können Sie versuchen, ein Objekt zu erstellen, das vom gewünschten Wert erbt, und prüfen, ob es funktioniert hat.
Beides Object.create
und Object.getPrototypeOf
erfordern 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;
}
Einige neue ECMAScript 6-Möglichkeiten
ECMAScript 6 führt einige neue indirekte Methoden ein, um zu überprüfen, ob ein Wert ein Objekt ist. Sie verwenden den zuvor gesehenen Ansatz, um den Wert an einen Code zu übergeben, für den ein Objekt erforderlich ist, das in eine try
Anweisung eingeschlossen ist, um Fehler abzufangen. Einige versteckte Beispiele, die es nicht wert sind, kommentiert zu werden
Hinweis: Ich habe absichtlich einige Ansätze wie Object.getPrototypeOf(value)
(ES5) und Reflect
Methoden (ES6) übersprungen, weil sie wesentliche interne Methoden aufrufen, die böse Dinge tun können, z. B. wenn value
es sich um einen Proxy handelt. Aus Sicherheitsgründen beziehen sich meine Beispiele nur, value
ohne direkt darauf zuzugreifen.
Versuche dies
if (objectName instanceof Object == false) {
alert('Not an object');
}
else {
alert('An object');
}
Object.prototype instanceof Object
-> false. Object.create(null) instanceof Object
-> falsch.
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
In Javascript, null
, Object
, Array
, Date
und function
s sind alle Objekte. Obwohl null
ist etwas erfunden. Es ist also besser, nach dem null
ersten zu suchen, um festzustellen, dass es nicht null ist.
Überprüfung auf typeof o === 'object'
Garantien, o
die ein Objekt sind. Ohne diese Prüfung Object.prototype.toString
wäre es bedeutungslos, da es Objekt für alles zurückgeben würde, auch für undefined
und null
! Zum Beispiel: toString(undefined)
kehrt zurück [object Undefined]
!
Nach der typeof o === 'object'
Prüfung wird toString.call (o) eine große Methode zu prüfen , ob o
ein Objekt ist, ein abgeleitetes Objekt wie Array
, Date
oder ein function
.
In der isDerivedObject
Funktion wird geprüft, ob es sich um o
eine Funktion handelt. Denn auch ein Objekt funktionieren, deshalb ist es da. Wenn dies nicht der Fall ist, wird die Funktion als false zurückgegeben. Beispiel: isDerivedObject(function() {})
würde zurückkehren false
, aber jetzt kehrt es zurück true
.
Man kann jederzeit die Definition eines Objekts ändern. Man kann diese Funktionen also entsprechend ändern.
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(){})
);
Wenn Sie prüfen möchten, ob das prototype
für ein object
ausschließlich von kommt Object
. Filtert String
, Number
, Array
, Arguments
etc.
function isObject (n) {
return Object.prototype.toString.call(n) === '[object Object]';
}
Oder als Pfeilfunktion mit einem Ausdruck (ES6 +)
const isObject = n => Object.prototype.toString.call(n) === '[object Object]'
return Object.prototype.toString.call(n) === '[object Object]'
null
Scheck auch entfernen , weilObject.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
Ich wurde gebeten, weitere Details anzugeben. Die sauberste und verständlichste Methode, um zu überprüfen, ob unsere Variable ein Objekt ist, ist typeof myVar
. Es gibt eine Zeichenfolge mit einem Typ zurück (z "object"
."undefined"
).
Leider haben entweder Array und null auch einen Typ object
. Um nur reale Objekte aufzunehmen, muss die Vererbungskette mit dem instanceof
Operator überprüft werden . Es wird null eliminiert, aber Array hat Object in der Vererbungskette.
Die Lösung lautet also:
if (myVar instanceof Object && !(myVar instanceof Array)) {
// code for objects
}
/./ instanceof Object //true
Wenig spät ... für "einfache Objekte" (ich meine, wie {'x': 5, 'y': 7}) habe ich diesen kleinen Ausschnitt:
function isPlainObject(o) {
return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
false
:(typeof o == 'object');
}
Es wird die nächste Ausgabe generiert:
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
Es funktioniert immer bei mir. If gibt nur dann "true" zurück, wenn der Typ "o" "object" ist, aber keine Null, kein Array oder keine Funktion. :) :)
lodash hat isPlainObject , nach dem viele suchen, die auf diese Seite kommen. Es gibt false zurück, wenn eine Funktion oder ein Array angegeben wird.
_.isObject
welche Übereinstimmungen das sind, was JS als Objekt betrachtet. Normalerweise muss ich jedoch zwischen einem Objektliteral und einem Array unterscheiden, und genau das kann _.isPlainObject
ich tun.
Das wird funktionieren. Es ist eine Funktion, die true, false oder möglicherweise null zurückgibt.
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
eher als Ergebnis für den endgültigen Test als erhaltenfalse
. Siehe Wann sollte ich Änderungen am Code vornehmen?
Da es eine Menge Verwirrung darüber zu geben scheint, wie dieses Problem richtig behandelt werden soll, lasse ich meine 2 Cent (diese Antwort ist spezifikationskonform und liefert unter allen Umständen korrekte Ergebnisse):
Testen auf Grundelemente:
undefined
null
boolean
string
number
function isPrimitive(o){return typeof o!=='object'||null}
Ein Objekt ist kein Primitiv:
function isObject(o){return !isPrimitive(o)}
Oder alternativ:
function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}
Testen für jedes Array:
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];
}
}());
Testen auf Objekte ohne: Date
RegExp
Boolean
Number
String
Function
beliebiges Array
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];
}
}());
Wenn alles andere fehlschlägt, benutze ich Folgendes:
var isObject = function(item) {
return item.constructor.name === "Object";
};
item.constructor === Object
?
null
wirft eine AusnahmeUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
oder wegen constructor.name
?
Die Ramda- Funktionsbibliothek bietet eine wunderbare Funktion zum Erkennen von JavaScript-Typen.
Die volle Funktion umschreiben :
function type(val) {
return val === null ? 'Null' :
val === undefined ? 'Undefined' :
Object.prototype.toString.call(val).slice(8, -1);
}
Ich musste lachen, als mir klar wurde, wie einfach und schön die Lösung war.
Anwendungsbeispiel aus der Ramda- Dokumentation :
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"
Nach der Lektüre und vielen Implementierungen auszuprobieren, habe ich bemerkt , dass nur sehr wenige Menschen für Werte zu überprüfen versuchen , wie JSON
, Math
, document
oder Gegenstände , die mit Prototypen Ketten länger als 1 Schritt.
Anstatt die typeof
Variable zu überprüfen und dann Randfälle wegzuhacken, dachte ich, es wäre besser, wenn die Überprüfung so einfach wie möglich gehalten wird, um zu vermeiden, dass eine Umgestaltung erforderlich ist, wenn neue Grundelemente oder native Objekte hinzugefügt werden, die sich als typeof
'Objekt' registrieren '.
Schließlich typeof
sagt Ihnen der Operator, ob etwas ein Objekt für JavaScript ist , aber die JavaScript-Definition eines Objekts ist für die meisten realen Szenarien (z typeof null === 'object'
. B. ) zu weit gefasst . Im Folgenden finden Sie eine Funktion, die bestimmt, ob eine Variable v
ein Objekt ist, indem im Wesentlichen zwei Überprüfungen wiederholt werden:
v
ist '[object Object]'
. v
wird durch den nächsten Prototyp in der Kette mit ersetzt v = Object.getPrototypeOf(v)
, aber auch direkt danach ausgewertet. Wenn der neue Wert von v
ist null
, bedeutet dies, dass jeder Prototyp einschließlich des Root-Prototyps (der sehr wohl der einzige Prototyp innerhalb der Kette gewesen sein könnte) die Prüfung in der while-Schleife bestanden hat und wir true zurückgeben können. Andernfalls wird eine neue Iteration gestartet.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
ist, null
wird ein Fehler ausgegeben ...
false
für das Objekt sein Object.assign({}, {constructor: null})
.
Es ist eine alte Frage, aber ich dachte, ich lasse das hier. Die meisten Leute prüfen, ob die Variable {}
ein Schlüssel-Wert-Paar bedeutet und nicht, welches Unterstreichungskonstrukt JavaScript für eine bestimmte Sache verwendet, denn um ehrlich zu sein, ist meistens alles in JavaScript ein Objekt. Also das aus dem Weg räumen. Wenn Sie tun...
let x = function() {}
typeof x === 'function' //true
x === Object(x) // true
x = []
x === Object(x) // true
// also
x = null
typeof null // 'object'
In den meisten Fällen möchten wir wissen, ob ein Ressourcenobjekt von einer API oder unser Datenbankaufruf vom ORM zurückgegeben wurde. Wir können dann testen, ob es kein Array
ist, nicht null
ist, kein Typ 'function'
ist und ein istObject
// 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
fürnew Date()
new Date()
Was ich gerne benutze, ist dies
function isObject (obj) {
return typeof(obj) == "object"
&& !Array.isArray(obj)
&& obj != null
&& obj != ""
&& !(obj instanceof String) }
Ich denke, in den meisten Fällen muss ein Datum die Prüfung als Objekt bestehen, daher filtere ich keine Daten heraus
Ich habe einen "neuen" Weg gefunden, um genau diese Art der Typprüfung anhand dieser SO-Frage durchzuführen: Warum gibt instanceof für einige Literale false zurück?
Daraus habe ich eine Funktion zur Typprüfung wie folgt erstellt:
function isVarTypeOf(_var, _type){
try {
return _var.constructor === _type;
} catch(ex) {
return false; //fallback for null or undefined
}
}
dann kannst du einfach machen:
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
Dies wird auf Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11 und Opera 43 getestet
Bearbeiten:
Wenn Sie auch überprüfen möchten, ob eine Variable null oder undefiniert ist, können Sie dies stattdessen verwenden:
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
Update von inancs Kommentar: Herausforderung angenommen: D.
Wenn Sie Vergleichsobjekte verlieren möchten, können Sie Folgendes versuchen:
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
}
}
}
Auf diese Weise können Sie genau wie inancs Kommentar vorgehen:
isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true
oder
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
nach Objekten suchen. Dies ist jedoch keine exakte Wissenschaft.
new Foo()
ein Foo
Objekt zurückgeben können, genauso wie Sie new String()
ein String
Objekt zurückgeben oder new Date()
ein Date
Objekt zurückgeben. Foo = function(){}; isVarTypeOf(new Foo(), Foo);
null
es sich um ein Objekt handelt).