Überprüfen Sie, ob ein Wert ein Objekt in JavaScript ist

1365

Wie überprüfen Sie, ob ein Wert ein Objekt in JavaScript ist?

Danny Fox
quelle
4
Eine Variable ist eine Variable. Es kann sich auf ein Objekt beziehen. Möglicherweise möchten Sie auch "Objekt" definieren - wie die Antworten und Kommentare zeigen, gibt es verschiedene widersprüchliche Definitionen (z. B. ob nulles sich um ein Objekt handelt).
8
OP, IMO, Sie sollten die Antwort von @ Daan akzeptieren, da dies die beste Lösung ist und über anderen Antworten aufgeführt werden sollte, damit sie zuerst angezeigt wird. (Keine Beleidigung für andere, die auch gute Antworten haben.)
Tiffon
2
IMHO hängt es wirklich davon ab, was Sie (derjenige, der nach einer Antwort auf diese Frage sucht) als Objekt betrachten und warum Sie es überprüfen. Diese Frage gibt verschiedene Antworten , wenn Sie versuchen Arrays zu unterscheiden (die sind Objekte) von anderen Objekten oder wenn Sie versuchen , skalare Werte von „Vektoren“ zu trennen. Und ob null (das ist ein Objekt, je nach Typ) oder Funktionen (das sind Objekte) ausgeschlossen werden sollen oder nicht, hängt wirklich davon ab, warum Sie es überprüfen. Deshalb gibt es so viele Antworten und die meisten davon sind im Kontext richtig.
FrancescoMM
const isEmpty = thing => {typeof thing === "Objekt"? ! Ding || ! Object.keys (thing) .length :! Ding && thing! == 0};
Mayur S
1
Es wäre großartig, wenn Sie zunächst sagen könnten, was genau Sie unter "ist ein Objekt" verstehen. (Oder sagen Sie ausdrücklich, dass ein Teil der Antwort, die Sie suchen, darin besteht, verschiedene populäre Bedeutungen von "ist ein Objekt" festzunageln und dann zwischen ihnen zu unterscheiden.) Fehlt dies, sprechen alle aneinander vorbei.
Don Hatch

Antworten:

520

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.

Michael Krelin - Hacker
quelle
208
typeofist ein Operator, also keine Notwendigkeit für ().
Yoshi
67
Ja, keine Notwendigkeit. Ich bevorzuge es einfach so.
Michael Krelin - Hacker
150
@ MichaelKrelin-Hacker: Das ist bedauerlich, da es die Leute verwirrt .
RightSaidFred
11
@RightSaidFred, ich habe keine Erklärung dafür, aber ich bin absolut nicht geneigt, zusätzliche Klammern in diese Ausdrücke einzufügen :)
Michael Krelin - Hacker
117
Diese Antwort ist falsch. typeofGibt 'Objekt' für null zurück, das kein Objekt ist, und instanceoffunktioniert nicht für Objekte, die mit erstellt wurden Object.create(null).
Nikolai
1635

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.

Futter
quelle
31
Funktionen sind ebenfalls Objekte und sollten in Ihren Scheck aufgenommen werden.
JS_Riddler
4
In diesem Fall wäre yourVariable !== nulleine bessere Praxis?
Hippietrail
9
@RightSaidFred Scheint, dass 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.
Konstantin Smolyanin
2
@Orion die einfache Antwort ist, dass Arrays als Objekte betrachtet werden. Für eine detailliertere Antwort müssen Sie nachlesen, 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.
Matt Fenwick
8
@Tresdin Der beste Weg ist zu rennen 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]
Jose Rui Santos
539

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
  • alles stammte von Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} - benutzerdefinierte Funktionen
    • C.prototype- die Prototyp-Eigenschaft einer benutzerdefinierten Funktion: Dies ist kein C Prototyp
      • new C() - "Neu" - eine benutzerdefinierte Funktion
    • Math
    • Array.prototype
      • Arrays
    • {"a": 1, "b": 2} - Objekte, die in Literalschreibweise erstellt wurden
    • new Number(3) - Umhüllungen von Grundelementen
    • ... viele andere Dinge ...
  • Object.create(null)
  • alles stammte von einem 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({})
Matt Fenwick
quelle
22
obj === Object(obj)Gibt truefür Arrays zurück.
Onur Yıldırım
5
var x = []; console.log(x === Object(x)); // return true
Illuminator
6
@ Illuminator-Arrays sind Objekte in Javascript, wie ich in meiner Antwort erwähnt habe.
Matt Fenwick
1
getPrototypeOffunktioniert zB nicht mit widerrufenen Proxys, die Objekte sind, aber werfen.
Oriol
2
Warum nicht ({}).toString.apply(obj) === '[object Object]'unterscheidet dies zwischen Arrays und Objekten, die keine Arrays sind
MauricioJuanes
295

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;
};
Daan
quelle
57
In Javascript ist ein Array auch ein Objekt, daher möchten Sie das Array die meiste Zeit ausschließen:return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
Daan
22
Warum sollten Sie ein Array ausschließen? Sie sind vollwertige Objekte.
Nikolai
65
Weil Sie die meiste Zeit ein {} von einem [] unterscheiden möchten, zum Beispiel als Eingabe in eine Funktion
Daan
5
@ Nickolai ..und zum Durchlaufen verschachtelter Objekte.
Ricky Boyce
6
Gute Antwort. Griffe nullauch. Sollte die akzeptierte Antwort sein.
Tiffon
180

Object.prototype.toString.call(myVar) wird zurückkehren:

  • "[object Object]" wenn myVar ein Objekt ist
  • "[object Array]" wenn myVar ein Array ist
  • usw.

Weitere Informationen dazu und warum es eine gute Alternative zu typeof ist, finden Sie in diesem Artikel .

Christophe
quelle
12
Das habe ich kürzlich gelernt typeof [] === 'object'-> true. Das ist es, was Sie diese Methode brauchen.
Jondlm
3
@Christophe Unterscheidet nicht zwischen Grundelementen und Objekten . Object.prototype.toString.call(3)-> "[object Number]". Object.prototype.toString.call(new Number(3))-> "[object Number]"
Matt Fenwick
3
@ MattFenwick Ich glaube nicht, dass dies die Art von "Objekt" ist, das das OP zu identifizieren versucht
Christophe
3
@Christophe warum denkst du das? IMHO erscheint es mir am vernünftigsten, in Ermangelung einer anderen Definition des OP für "Objekt" diejenige zu wählen, die in der gesamten ECS-Spezifikation einheitlich verwendet wird.
Matt Fenwick
getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Mr. Polywhirl
116

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
zupa
quelle
isObjectfunktioniert nur mit Objektliteralen. Wenn ich einen benutzerdefinierten Typ erstelle, eine Instanz des Typs erstelle und ihn false
teste
3
@zupa: was !! a macht?
4
@ 3000 gut, wenn wir den (!! a) Teil weglassen, stürzt er ab, weil null und undefined keine Konstruktoren haben. (!! a) filtert sie heraus. Beantwortet das deine Frage?
zupa
2
@zupa @ 3000 Boolean(a)ist länger, aber weitaus intuitiver. Verwenden Sie einfach nicht new Boolean(a): ( hier ist der Grund )!
JayVee
10
Überrascht ist die beste Antwort so weit unten auf der Seite. Dies beantwortet im Grunde die Frage, ob dies in JSON als etwas dargestellt wird, das mit einem {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.
Kip
81

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

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

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

2540625
quelle
3
Was ist mit console.log (isObject (neues Datum ()))? Warum sollte ein Datum ein Objekt sein, ein Array jedoch nicht?
schirrmacher
5
@macher Weil 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.
StanE
1
@ StanE Arrays sind definitiv Objekte. Nicht sicher, warum Sie denken, dass Objekte keine 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.
Oriol
4
@Oriol Ich habe weder geschrieben, dass Arrays keine Objekte sind, noch habe ich geschrieben, dass Objekte keine 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.
StanE
2
typeof nullist "object"nicht "undefined".
2540625
80

Mit Funktion Array.isArray:

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

Ohne Funktion 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! 🙂

V. Kovpak
quelle
beste Antwort! funktioniert für viele der hier
Prieston
Da dies für isObject (myDateObject) false zurückgibt, ist dies keine Antwort auf die Frage. Es wird nicht angegeben, ob eine Variable ein Objekt ist, sondern nur, ob es sich um ein Objekt einer bestimmten Klasse handelt. Die Frage hier ist für eine generische Funktion, die für jedes Objekt true zurückgibt.
Yetanotherjosh
@Yetanotherjosh Es ist in der Tat eine Antwort - Sie haben den Fall erwähnt, der in der Antwort beschrieben ist, und den Punkt - Sie müssen isDatefür Ihr DateObject den Zweck verwenden, robusten Code zu schreiben, sonst haben Sie eine spröde isObjectMethode.
V. Kovpak
@VladimirKovpak Die Verwendung 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.
Yetanotherjosh
@Yetanotherjosh Ich habe meine Antwort aktualisiert. Und 1 weiteren Fall hinzugefügt.
V. Kovpak
40

Oh mein Gott! Ich denke, das könnte kürzer sein als je zuvor. Sehen wir uns das an:

Kurz- und Schlusscode

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

Erklärt

Rückgabetypen

Typ von JavaScript-Objekten (einschließlich null) gibt zurück"object"

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

Überprüfung ihrer Konstruktoren

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

Einführung in Function.name

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

Erisan Olasheni
quelle
3
Ich mag dieses wirklich, kurz und auf den Punkt. Soweit ich sehen kann, scheitert es nur an einer Sache. wenn obj = Object.create(null)und warum würdest du das überhaupt tun ...?
Julian Knight
29

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);
Alireza
quelle
Sie möchten auch überprüfen, ob es sich nicht um ein Array handelt. also Funktion isObject (obj) {return obj! == null && typeof obj === 'object' &&! Array.isArray (obj); }
Matt Goo
Ich stimme Ihnen zu, aber wie Sie im Kommentar sehen, wird es in AngularJs so gemacht, und ich erwähne es im Kommentar vor der Funktion. Sie zählen das Array als Objekt. Weitere Informationen finden Sie hier: docs .angularjs.org / api / ng / function / angular.isObject
Alireza
24

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.

letztes Kind
quelle
Warum wird typeof === 'function' als Objekt betrachtet? Eine Funktion ist kein Objekt, nicht wahr? "new myFunc ()" wird ein Objekt, ja, aber eine einfache Funktion?
StanE
Nein, jede Funktion ist ein Objekt in Javascript, unabhängig davon, wie sie erstellt wurde. Sie können Eigenschaften für sie festlegen (es sei denn, sie sind eingefroren), sie sind instanceof Object, zwei identische Funktionsliterale sind nicht streng gleich, sie werden als Referenz übergeben usw.
letztes Kind
21

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.

kushalvm
quelle
2
Bemerkenswerterweise kehrt dies auch zurück false (wie gewünscht) zurückgegeben wird, wenn anyVares sich um eine Funktion handelt.
Jamie Birch
18

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:

  • Es wird "object"für zurückgegeben null, was zum Typ Null gehört.
  • Es wird "function"für aufrufbare Objekte zurückgegeben, die zum Objekttyp gehören.
  • Es kann (fast) alles zurückgeben, was es für nicht standardmäßige nicht aufrufbare Objekte wünscht. Zum Beispiel schien IE zu mögen "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

Umfassende, aber nicht erschöpfende Liste geeigneter Methoden zum Testen, ob ein Wert zum Objekttyp gehört.

  • 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.

Oriol
quelle
2
"Nur meine Antwort und Daans sind völlig richtig." ist etwas anmaßend, da ich Ihren ersten beiden Sätzen überhaupt nicht zustimme .
zzzzBov
1
@zzzzBov Nun, ich habe mir alle Antworten angesehen und sie stellen nicht sicher, dass immer die richtige Antwort zurückgegeben wird, außer meiner und Daans. Ich kann den meisten von ihnen reproduzierbare Gegenbeispiele geben. Die anderen empfehlen zu prüfen, ob typeof "function" oder "object" zurückgibt. Wie ich bereits erläutert habe, erlaubt die Spezifikation für einige Objekte andere Ergebnisse. Die Antwort von Matt Fenwick enthält dieselbe richtige Antwort wie die von Daan, enthält aber auch falsche.
Oriol
1
Ich war mit der Annahme nicht einverstanden, dass Ihre Antwort "völlig richtig" ist, und argumentiere, dass andere "nicht sicherstellen, dass immer die richtige Antwort zurückgegeben wird", meine Position in keiner Weise widerlegen. Darüber hinaus erhebt die Frage keinen Anspruch darauf, welche Eingabe welche Ausgabe erzeugen soll.
zzzzBov
1
@zzzzBov Die Frage fragt, wie überprüft werden soll, ob etwas ein Objekt ist. ECMAScript definiert, was ein Objekt ist, daher verwende ich diese Definition. Ich kann keine andere vernünftige Interpretation sehen. Antworten, die andere Aufgaben ausführen (z. B. das Ausschließen von Arrays), können unter bestimmten Umständen hilfreich sein, prüfen jedoch nicht, ob es sich bei einem Objekt um ein Objekt handelt.
Oriol
@Oriol Vielleicht könnten Sie eine Antwort auf diese Frage geben. Warum gibt es in JavaScript keine integrierte Methode, um zu überprüfen, ob ein Objekt ein einfaches Objekt ist? ?
guest271314
15

Versuche dies

if (objectName instanceof Object == false) {
  alert('Not an object');
}
else {
  alert('An object');
}
Talha
quelle
14
Warum dobule du Boolesche?
Jkutianski
5
Dabei fehlen zwei Fälle: Object.prototype instanceof Object-> false. Object.create(null) instanceof Object-> falsch.
Matt Fenwick
Was ist mit Daten? new Date() instanceof Object => true
mauron85
13

Gebrauchsfertige Funktionen zur Überprüfung

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

Erläuterung

  • 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.


Tests

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(){})
);

Inanc Gumus
quelle
13

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]'
sasi
quelle
1
Dies ist der beste Weg, aber ich würde es noch einfacher machen, indem ich in der 2. Zeile:return Object.prototype.toString.call(n) === '[object Object]'
Mesqueeb
1
Sie können den nullScheck auch entfernen , weilObject.prototype.toString.call(null) === '[object Null]'
Gust van de Wal
12
var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true

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

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

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
}
Kania
quelle
/./ instanceof Object //true
Yckart
11

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

Emilio Grisolía
quelle
Wie in den vorherigen Antworten erwähnt, schlägt Ihr Ansatz im Fall des Date-Objekts fehl.
Grzegorz Pawlik
9

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.

Klopfen
quelle
Perfekt! Ich wusste, _.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.
Kalk
9

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

Pizzarob
quelle
2
@SeregPie In Zukunft sollten Sie den Code in den Antworten nicht mehr bearbeiten. Wie diese Antwort steht, habe ich beim Testen nulleher als Ergebnis für den endgültigen Test als erhaltenfalse . Siehe Wann sollte ich Änderungen am Code vornehmen?
Nick
9

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];
    }
}());
c7x43t
quelle
8

Wenn alles andere fehlschlägt, benutze ich Folgendes:

var isObject = function(item) {
   return item.constructor.name === "Object";
}; 
Michal
quelle
1
Warum der Stringvergleich, warum nicht einfach item.constructor === Object?
K3 --- rnc
nullwirft eine AusnahmeUncaught TypeError: Cannot read property 'constructor' of null(…)
Vitim.us
@rounce Ich möchte ältere IE-Versionen unterstützen. Warum funktioniert das nicht im IE? Wegen der indexOfoder wegen constructor.name?
Jankapunkt
8

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"
DaveGauer
quelle
8

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:

  1. Es wird eine Schleife gestartet, die so lange fortgesetzt wird, wie die stringifizierte Version von vist '[object Object]'.
    Ich wollte, dass das Ergebnis der Funktion genau den folgenden Protokollen entspricht, daher ist dies die einzige "Objektivität" -Kriterium, mit der ich am Ende endete. Wenn dies fehlschlägt, gibt die Funktion sofort false zurück.
  2. 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'}))))

Gust van de Wal
quelle
6
if(typeof value === 'object' && value.constructor === Object)
{
    console.log("This is an object");
}
Mahak Choudhary
quelle
1
Wenn dies der Fall valueist, nullwird ein Fehler ausgegeben ...
Gershom
Und natürlich wird es falsefür das Objekt sein Object.assign({}, {constructor: null}).
user4642212
6

Wenn Sie explizit überprüfen möchten, ob der angegebene Wert ist {}.

function isObject (value) {
 return value && typeof value === 'object' && value.constructor === Object;
}
Carlos
quelle
6
const isObject = function(obj) {
  const type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

!!objist eine Abkürzung für die Überprüfung, ob sie objwahr ist (um herauszufiltern null)

Ira
quelle
6

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
Gilbert
quelle
Pops truefürnew Date()
Toddmo
1
@toddmo danke für den Hinweis. Jetzt gibt der Beispielcode false fürnew Date()
Gilbert
4

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

JohnPan
quelle
4

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
am05mhz
quelle
Dies kann nicht erkennen, ob eine neue Klasse ein Objekt ist. isVarTypeOf (new (Funktion Foo () {}), Object) // Dies gibt false anstelle von true zurück. Siehe meine Antwort unten für die richtige Überprüfung.
Inanc Gumus
Sie können jedoch instanceofnach Objekten suchen. Dies ist jedoch keine exakte Wissenschaft.
Inanc Gumus
@inanc, nun, das liegt daran, dass Sie 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);
Dies
Ja, das sage ich eigentlich: Sie prüfen gerade nicht, ob es sich um ein Objekt handelt.
Inanc Gumus
@inanc Cheers, ich suchte nach einer Möglichkeit zur Typprüfung (nicht nur Objekt), kam zu dieser Seite und der anderen Seite, dann war ich zu aufgeregt, dass ich den Kontext dieser Frage vergessen habe, mein schlechtes :)
am05mhz