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 nullauch objectin 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.
typeofist ein Operator, also keine Notwendigkeit für ().
typeofGibt 'Objekt' für null zurück, das kein Objekt ist, und instanceoffunktioniert 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 !== nulleine 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.
typeofda 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'truenullundefinedWas ist ein Objekt (dh kein Primitiv)?
Object.prototypeObject.prototype
Function.prototype
ObjectFunctionfunction C(){} - benutzerdefinierte FunktionenC.prototype- die Prototyp-Eigenschaft einer benutzerdefinierten Funktion: Dies ist kein C Prototyp
new C() - "Neu" - eine benutzerdefinierte FunktionMathArray.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.getPrototypeOfdie 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 truefür Arrays zurück.
var x = []; console.log(x === Object(x)); // return true
getPrototypeOffunktioniert 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]'
nullauch. 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
isObjectfunktioniert 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 falsezurückgegeben. Der nullTest 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 lengthzum 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.
lengthEigenschaft 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.
lengthEigenschaft haben können (ich meinte, dass Objektliterale lengthstandardmäß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 nullist "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, isRegExpusw. 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).
isObjectfunktioniert nicht, wenn die Object.create(null)interne Implementierung hierObject.create erläutert wird , aber Sie können sie isObjectin 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! 🙂
isDatefür Ihr DateObject den Zweck verwenden, robusten Code zu schreiben, sonst haben Sie eine spröde isObjectMethode.
Datein meinem Kommentar wurde schlecht gewählt, weil ja, die Antwort diskutiert Date. Ist Dateaber 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 constructorEigenschaft 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.nameGibt 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, undefinedund null) sollte aber für alles andere true zurück (einschließlich Number, Booleanund StringObjekte). Beachten Sie, dass JS nicht definiert, welche "Host" -Objekte, wie z. B. windowoder 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.toStringTagjetzt das Anpassen der Ausgabe von möglich ist Object.prototype.toString.call(...), kann die isPlainObjectobige Funktion falsein 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 anyVares sich um eine Funktion handelt.
Der vernünftigste Weg, den Typ eines Wertes zu überprüfen, scheint der typeofOperator 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.typeofist 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 typeofkeinem 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 typeofempfehle 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 ObjectKonstruktor 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 Objectweder 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 tryAnweisungen 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 thisWert 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.createund Object.getPrototypeOferfordern 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 tryAnweisung 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 ReflectMethoden (ES6) übersprungen, weil sie wesentliche interne Methoden aufrufen, die böse Dinge tun können, z. B. wenn valuees sich um einen Proxy handelt. Aus Sicherheitsgründen beziehen sich meine Beispiele nur, valueohne 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, Dateund functions sind alle Objekte. Obwohl nullist etwas erfunden. Es ist also besser, nach dem nullersten zu suchen, um festzustellen, dass es nicht null ist.
Überprüfung auf typeof o === 'object'Garantien, odie ein Objekt sind. Ohne diese Prüfung Object.prototype.toStringwäre es bedeutungslos, da es Objekt für alles zurückgeben würde, auch für undefinedund 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 oein Objekt ist, ein abgeleitetes Objekt wie Array, Dateoder ein function.
In der isDerivedObjectFunktion wird geprüft, ob es sich um oeine 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 prototypefür ein objectausschließlich von kommt Object. Filtert String, Number, Array, Argumentsetc.
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]'
nullScheck 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 instanceofOperator ü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.
_.isObjectwelche Übereinstimmungen das sind, was JS als Objekt betrachtet. Normalerweise muss ich jedoch zwischen einem Objektliteral und einem Array unterscheiden, und genau das kann _.isPlainObjectich 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
nulleher 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?
nullwirft eine AusnahmeUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOfoder 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, documentoder Gegenstände , die mit Prototypen Ketten länger als 1 Schritt.
Anstatt die typeofVariable 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 typeofsagt 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 vein Objekt ist, indem im Wesentlichen zwei Überprüfungen wiederholt werden:
vist '[object Object]'. vwird durch den nächsten Prototyp in der Kette mit ersetzt v = Object.getPrototypeOf(v), aber auch direkt danach ausgewertet. Wenn der neue Wert von vist 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");
}
valueist, nullwird ein Fehler ausgegeben ...
falsefü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 Arrayist, nicht nullist, 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
truefü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
instanceofnach Objekten suchen. Dies ist jedoch keine exakte Wissenschaft.
new Foo()ein FooObjekt zurückgeben können, genauso wie Sie new String()ein StringObjekt zurückgeben oder new Date()ein DateObjekt zurückgeben. Foo = function(){}; isVarTypeOf(new Foo(), Foo);
nulles sich um ein Objekt handelt).