Come si controlla se un valore è un oggetto in JavaScript?
Come si controlla se un valore è un oggetto in JavaScript?
Risposte:
AGGIORNAMENTO :
Questa risposta è incompleta e dà risultati fuorvianti . Ad esempio, null
è anche considerato di tipo object
in JavaScript, per non parlare di molti altri casi limite. Seguire le raccomandazioni seguenti e passare all'altra "risposta più votata (e corretta!)" .
Risposta originale :
Prova a usare typeof(var)
e / o var instanceof something
.
EDIT: Questa risposta dà un'idea di come esaminare le proprietà di variabili, ma è non è una ricetta a prova di proiettile (dopo tutto non c'è ricetta a tutti!) Per verificare se si tratta di un oggetto, lontano da esso. Dato che le persone tendono a cercare qualcosa da copiare da qui senza fare alcuna ricerca, consiglio vivamente di rivolgersi all'altra, la più votata (e corretta!) Risposta.
typeof
è un operatore, quindi non è necessario ()
.
typeof
restituisce 'object' per null, che non è un oggetto e instanceof
non funziona per gli oggetti creati usando Object.create(null)
.
Se typeof yourVariable === 'object'
è un oggetto o null. Se vuoi escludere null, fallo e basta typeof yourVariable === 'object' && yourVariable !== null
.
yourVariable !== null
una pratica migliore?
typeof null == 'object'
non verrà risolto in ES6 . Dissero:This proposal has been rejected. It was implemented in V8 but it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
typeof
perché ha alcuni casi speciali che non hanno necessariamente molto senso. Se stai cercando di distinguere tra matrici e oggetti che non sono matrici, sicuramente non vuoi usare typeof
.
Object.prototype.toString.call(yourVar)
, essendo YourVar ciò che devi ispezionare. In caso di array, Object.prototype.toString.call([1,2])
ritorna[object Array]
Definiamo "oggetto" in Javascript . Secondo i documenti MDN , ogni valore è un oggetto o una primitiva:
valore primitivo, primitivo
Un dato che non è un oggetto e non ha alcun metodo. JavaScript ha 5 tipi di dati primitivi: stringa, numero, booleano, null, non definito.
Che cos'è una primitiva?
3
'abc'
true
null
undefined
Che cos'è un oggetto (cioè non un primitivo)?
Object.prototype
Object.prototype
Function.prototype
Object
Function
function C(){}
- funzioni definite dall'utenteC.prototype
- la proprietà prototipo di una funzione definita dall'utente: questo non C
è un prototipo
new C()
- "nuovo": una funzione definita dall'utenteMath
Array.prototype
{"a": 1, "b": 2}
- oggetti creati usando la notazione letteralenew Number(3)
- involucri attorno ai primitiviObject.create(null)
Object.create(null)
Come verificare se un valore è un oggetto
instanceof
di per sé non funzionerà, perché manca due casi:
// oops: isObject(Object.prototype) -> false
// oops: isObject(Object.create(null)) -> false
function isObject(val) {
return val instanceof Object;
}
typeof x === 'object'
non funzionerà, a causa di falsi positivi ( null
) e falsi negativi (funzioni):
// oops: isObject(Object) -> false
function isObject(val) {
return (typeof val === 'object');
}
Object.prototype.toString.call
non funzionerà, a causa di falsi positivi per tutti i primitivi:
> Object.prototype.toString.call(3)
"[object Number]"
> Object.prototype.toString.call(new Number(3))
"[object Number]"
Quindi io uso:
function isObject(val) {
if (val === null) { return false;}
return ( (typeof val === 'function') || (typeof val === 'object') );
}
Anche la risposta di Daan sembra funzionare:
function isObject(obj) {
return obj === Object(obj);
}
perché, secondo i documenti MDN :
Il costruttore Object crea un wrapper di oggetti per il valore dato. Se il valore è nullo o indefinito, creerà e restituirà un oggetto vuoto, altrimenti restituirà un oggetto di un tipo che corrisponde al valore dato. Se il valore è già un oggetto, restituirà il valore.
Un terzo modo che sembra funzionare (non so se è al 100%) è quello di utilizzare Object.getPrototypeOf
, che genera un'eccezione se il suo argomento non è un oggetto:
// 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)
ritorna true
per gli array.
var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
non funziona ad es. con proxy revocati, che sono oggetti ma lanciano.
({}).toString.apply(obj) === '[object Object]'
questo distingue tra matrici e oggetti che non sono matrici
underscore.js fornisce il seguente metodo per scoprire se qualcosa è veramente un oggetto:
_.isObject = function(obj) {
return obj === Object(obj);
};
AGGIORNARE
A causa di un bug precedente in V8 e di una minore ottimizzazione della micro velocità, il metodo è il seguente da underscore.js 1.7.0 (agosto 2014):
_.isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
null
. Dovrebbe essere la risposta accettata.
Object.prototype.toString.call(myVar)
tornerà:
"[object Object]"
se myVar è un oggetto"[object Array]"
se myVar è un arrayPer ulteriori informazioni su questo e perché è una buona alternativa a typeof, leggi questo articolo .
typeof [] === 'object'
-> true
. Questo è quello che ti serve questo metodo.
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];};
Per un semplice controllo su Oggetto o Matrice senza chiamata di funzione aggiuntiva (velocità). Come anche pubblicato qui .
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 () - Nota: utilizzare solo per valori letterali Object, poiché restituisce false per oggetti personalizzati, come new Date o new YourCustomObject.
isObject = function(a) {
return (!!a) && (a.constructor === Object);
};
console.log(isObject( )); // false
console.log(isObject( null)); // false
console.log(isObject( true)); // false
console.log(isObject( 1)); // false
console.log(isObject( 'str')); // false
console.log(isObject( [])); // false
console.log(isObject(new Date)); // false
console.log(isObject( {})); // true
isObject
Funziona solo con oggetti letterali. Se creo un tipo personalizzato, creo un'istanza del tipo e lo collaudo, restituiscefalse
Boolean(a)
è più lungo, ma molto più intuitivo. Basta non usare new Boolean(a)
: ( ecco perché )!
{
personaggio. Nel caso dell'array, purché non sia necessario supportare IE <9, è possibile utilizzare Array.isArray()
per determinare se qualcosa è un array. Passa tutti i casi di test forniti.
Mi piace semplicemente:
function isObject (item) {
return (typeof item === "object" && !Array.isArray(item) && item !== null);
}
Se l'elemento è un oggetto JS e non è un array JS e non è null
... se tutti e tre si dimostrano veri, restituire true
. Se una delle tre condizioni fallisce, il &&
test cortocircuita e false
verrà restituito. Il null
test può essere omesso se lo si desidera (a seconda di come si usa null
).
DOCS:
http://devdocs.io/javascript/operators/typeof
http://devdocs.io/javascript/global_objects/object
new Date()
restituisce un oggetto. Un array è dal punto di vista logico non un oggetto, anche se JavaScript li gestisce e li segnala come tali. In pratica, tuttavia, non è utile vederli uguali, perché non lo sono. Un oggetto non ha length
attributi per esempio e non ha metodi come push (). E a volte potresti voler dare una funzione con parametri sovraccarichi, dove devi fare la differenza tra un array o un oggetto, specialmente se altri parametri dipendono da quale è stato dato.
length
proprietà o metodi simili push
, Object.create(Array.prototype)
è un banale controesempio di un oggetto non-array che li possiede. Ciò che rende speciali le matrici è che sono oggetti esotici con un metodo interno essenziale [[DefineOwnProperty]] personalizzato, ma sono comunque oggetti.
length
proprietà (intendevo dire che i valori letterali degli oggetti non hanno length
attributi per impostazione predefinita). Ho scritto che le matrici non sono oggetti da un punto di vista logico . Sto parlando della logica del programma. Talvolta è necessario verificare se un array è un array "reale" e sicuramente non un oggetto "reale". Questo è ciò che Array.isArray()
serve. Immagina di avere una funzione che accetta un oggetto o una matrice di oggetti. Il controllo di un attributo o metodo speciale è una soluzione sporca. Il modo nativo è sempre migliore.
typeof null
è "object"
, non è "undefined"
.
Array.isArray
:function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}
Array.isArray
:Sono rimasto sorpreso dal numero di voti per risposte sbagliate 😮
Solo 1 risposta ha superato i miei test !!! Qui ho creato la mia versione semplificata:
function isObject(o) {
return o instanceof Object && o.constructor === Object;
}
Per quanto mi riguarda, è chiaro e semplice e funziona! Ecco i miei test:
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
UNA VOLTA IN PIÙ: non tutte le risposte superano questo test !!! 🙈
Nel caso in cui sia necessario verificare che l'oggetto sia un'istanza di una particolare classe, è necessario controllare il costruttore con la propria particolare classe, come:
function isDate(o) {
return o instanceof Object && o.constructor === Date;
}
test semplice:
var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d)); // Will return: true
Di conseguenza, avrai un codice rigoroso e robusto!
Nel caso in cui non sarà possibile creare funzioni come isDate
, isError
, isRegExp
, ecc si può considerare l'opzione di utilizzare queste funzioni generalizzate:
function isObject(o) {
return o instanceof Object && typeof o.constructor === 'function';
}
non funzionerà correttamente per tutti i casi di test menzionati in precedenza, ma è abbastanza buono per tutti gli oggetti (semplici o costruiti).
isObject
non funzionerà in caso di Object.create(null)
implementazione interna di Object.create
cui è spiegato qui ma è possibile utilizzare isObject
in implementazioni più sofisticate:
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;
};
Esiste già un pacchetto creato su npm v1 basato su questa implementazione! E funziona per tutti i casi di test precedentemente descritti! 🙂
isDate
per yourDateObject con lo scopo di scrivere codice robusto altrimenti avrai un isObject
metodo fragile .
Date
nel mio commento è stato scelto male perché sì, la risposta discute Date
. Ma Date
è solo una delle infinite classi possibili e il punto vale per qualsiasi altra classe. Esempio: class Foo() { }; var x = new Foo(); isObject(x)
ritorna false
. Non so esattamente quale sia il caso d'uso dell'OP, ma è facile concepire scenari in cui sarà impossibile conoscere tutte le classi possibili e verificare specificamente con ognuna di esse .
Dio mio! Penso che questo potrebbe essere più breve che mai, vediamo questo:
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
tipo di oggetti JavaScript (incluso null
) restituisce"object"
console.log(typeof null, typeof [], typeof {})
Il controllo sulla loro constructor
proprietà restituisce la funzione con i loro nomi.
console.log(({}).constructor) // returns a function with name "Object"
console.log(([]).constructor) // returns a function with name "Array"
console.log((null).constructor) //throws an error because null does not actually have a property
Function.name
restituisce un nome di sola lettura di una funzione o "anonymous"
per chiusure.
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
Nota: a partire dal 2018, Function.name potrebbe non funzionare in IE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility
Object.create(null)
e perché mai lo faresti comunque ...?
Ok, ti danno questo concetto prima di rispondere alla tua domanda, nelle funzioni JavaScript sono oggetto, anche nullo, oggetto, array e persino Data, così come si vede non c'è non è un modo semplice come typeof obj === 'oggetto', in modo da tutto quanto sopra menzionato tornerà vero , ma ci sono modi per verificarlo con la scrittura di una funzione o l'utilizzo di framework JavaScript, OK:
Ora, immagina di avere questo oggetto che è un oggetto reale (non nullo o funzione o matrice):
var obj = {obj1: 'obj1', obj2: 'obj2'};
JavaScript puro:
//that's how it gets checked in angular framework
function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
o
//make sure the second object is capitalised
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
o
function isObject(obj) {
return obj.constructor.toString().indexOf("Object") > -1;
}
o
function isObject(obj) {
return obj instanceof Object;
}
Puoi semplicemente usare una di queste funzioni come sopra nel tuo codice chiamandole e tornerà vero se è un oggetto:
isObject(obj);
Se stai usando un framework JavaScript, di solito hanno preparato questo tipo di funzioni per te, queste sono poche:
jQuery:
//It returns 'object' if real Object;
jQuery.type(obj);
Angolare:
angular.isObject(obj);
Underscore e Lodash:
//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);
Dipende da cosa intendi con "è un oggetto". Se vuoi tutto ciò che non è una primitiva , cioè cose su cui puoi impostare nuove proprietà, questo dovrebbe fare il trucco:
function isAnyObject(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
Esso esclude i primitivi (numeri pianura / NaN
/ Infinity
, le stringhe semplici, simboli, true
/ false
, undefined
e null
), ma deve restituire vero per tutto il resto (compresi Number
, Boolean
e String
gli oggetti). Si noti che JS non definisce quali oggetti "host", come window
o console
, devono essere restituiti quando utilizzati typeof
, quindi è difficile coprirli con un segno di spunta come questo.
Se vuoi sapere se qualcosa è un oggetto "semplice", cioè è stato creato come letterale {}
o con Object.create(null)
, potresti farlo:
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;
}
}
Modifica 2018 : poiché Symbol.toStringTag
ora consente di personalizzare l'output di Object.prototype.toString.call(...)
, la isPlainObject
funzione sopra potrebbe tornare false
in alcuni casi anche quando l'oggetto ha iniziato la sua vita come letterale. Probabilmente, per convenzione un oggetto con un tag stringa personalizzato non è più esattamente un oggetto normale, ma ciò ha ulteriormente confuso la definizione di ciò che un oggetto normale è persino in Javascript.
instanceof Object
, due letterali di funzioni identiche non sono strettamente uguali, vengono passati per riferimento, ecc.
Mio Dio, troppa confusione nelle altre risposte.
Risposta breve
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)
Per testarlo, esegui semplicemente le seguenti istruzioni nella console di Chrome.
Caso 1.
var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true
Caso 2
anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false
Caso 3
anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false
Spiegazione
Va bene, lasciamolo andare
typeof anyVar == 'object'
viene restituito vero da tre candidati - [], {} and null
,
anyVar instanceof Object
restringe questi candidati a due - [], {}
!(anyVar instanceof Array)
si restringe a uno solo - {}
Rulli di tamburo per favore!
Con ciò potresti aver già imparato a verificare la presenza di array in Javascript.
false
(come desiderato) quando anyVar
è una funzione.
Il modo più ragionevole per verificare il tipo di un valore sembra l' typeof
operatore. L'unico problema è che è terribilmente rotto:
"object"
per null
, che appartiene al tipo Null."function"
per oggetti richiamabili, che appartengono al tipo di oggetto."unknown"
. Gli unici risultati proibiti sono "function"
e tipi primitivi.typeof
è affidabile solo per i non null
primitivi. Quindi un modo per verificare se un valore è un oggetto sarebbe garantire che la stringa restituita da typeof
non corrisponda a una primitiva e che l'oggetto non lo sia null
. Tuttavia, il problema è che uno standard futuro potrebbe introdurre un nuovo tipo primitivo e il nostro codice lo considererebbe un oggetto. I nuovi tipi non vengono visualizzati di frequente, ma ad esempio ECMAScript 6 ha introdotto il tipo di simbolo.
Pertanto, invece di typeof
raccomandare solo approcci il cui risultato varia a seconda che il valore sia un oggetto o meno. Quanto segue intende essere a
Object
costruttore
Il Object
costruttore costringe l'argomento passato a un oggetto. Se è già un oggetto, viene restituito lo stesso oggetto.
Pertanto, è possibile utilizzarlo per forzare il valore su un oggetto e confrontarlo rigorosamente con il valore originale.
La seguente funzione richiede ECMAScript 3, che introduce ===
:
function isObject(value) { /* Requires ECMAScript 3 or later */
return Object(value) === value;
}
Mi piace questo approccio perché è semplice e auto-descrittivo, e un controllo analogo funzionerà anche per booleani, numeri e stringhe. Tuttavia, tieni presente che si basa sul fatto che il globale Object
non viene oscurato né alterato.
Costruttori
Quando si crea un'istanza di un costruttore, può restituire un valore diverso dall'istanza appena creata. Ma quel valore verrà ignorato a meno che non sia un oggetto.
La seguente funzione richiede ECMAScript 3, che ha permesso ai costruttori di restituire non oggetti. Prima di ECMAScript 3 che generava un errore, ma try
all'epoca non esistevano dichiarazioni.
function isObject(value) { /* Requires ECMAScript 3 or later */
return new function() { return value; }() === value;
}
Sebbene un po 'meno semplice dell'esempio precedente, questo non si basa su alcuna proprietà globale e quindi potrebbe essere il più sicuro.
this
valore
Le vecchie specifiche ECMAScript richiedevano che il this
valore fosse un oggetto. Introdotto ECMAScript 3 Function.prototype.call
, che ha permesso di chiamare una funzione con un this
valore arbitrario , ma costretto a un oggetto.
ECMAScript 5 ha introdotto una modalità rigorosa che ha rimosso questo comportamento, ma in modalità sciatta possiamo ancora (ma probabilmente non dovremmo) fare affidamento su di esso.
function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
return function() { return this === value; }.call(value);
}
[[Prototipo]]
Tutti gli oggetti ordinari hanno uno slot interno chiamato [[Prototype]], il cui valore determina da quale altro oggetto eredita. Il valore può essere solo un oggetto o null
. Pertanto, puoi provare a creare un oggetto che eredita dal valore desiderato e verificare se ha funzionato.
Entrambi Object.create
e Object.getPrototypeOf
richiedono 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;
}
Alcuni nuovi modi ECMAScript 6
ECMAScript 6 introduce alcuni nuovi modi indiretti per verificare se un valore è un oggetto. Usano l'approccio precedentemente visto per passare il valore ad un codice che richiede un oggetto, racchiuso in try
un'istruzione per rilevare errori. Alcuni esempi nascosti, non vale la pena commentare
Nota: ho intenzionalmente saltato alcuni approcci come Object.getPrototypeOf(value)
(ES5) e Reflect
metodi (ES6) perché chiamano metodi interni essenziali che potrebbero fare cose cattive, ad esempio se value
è un proxy. Per motivi di sicurezza i miei esempi fanno solo riferimento value
senza accedervi direttamente.
Prova questo
if (objectName instanceof Object == false) {
alert('Not an object');
}
else {
alert('An object');
}
Object.prototype instanceof Object
-> false. Object.create(null) instanceof Object
-> falso.
new Date() instanceof Object
=> true
function isObject(o) {
return null != o &&
typeof o === 'object' &&
Object.prototype.toString.call(o) === '[object Object]';
}
function isDerivedObject(o) {
return !isObject(o) &&
null != o &&
(typeof o === 'object' || typeof o === 'function') &&
/^\[object /.test(Object.prototype.toString.call(o));
}
// Loose equality operator (==) is intentionally used to check
// for undefined too
// Also note that, even null is an object, within isDerivedObject
// function we skip that and always return false for null
In Javascript, null
, Object
, Array
, Date
e function
s sono tutti gli oggetti. Anche se, null
è un po 'inventato. Quindi, è meglio controllare per null
primo, per rilevare che non è nullo.
Verifica delle typeof o === 'object'
garanzie che o
è un oggetto. Senza questo controllo, Object.prototype.toString
sarebbe privo di significato, poiché restituirebbe l'oggetto per tutto, anche per undefined
e null
! Ad esempio: toString(undefined)
ritorni [object Undefined]
!
Dopo typeof o === 'object'
controllo, toString.call (o) è un metodo per verificare se o
è un oggetto, un oggetto derivato come Array
, Date
o function
.
In isDerivedObject
funzione, verifica che o
sia una funzione. Perché, funzione anche un oggetto, ecco perché è lì. In caso contrario, la funzione verrà restituita come falsa. Esempio: isDerivedObject(function() {})
ritornerebbe false
, tuttavia ora ritorna true
.
Si può sempre cambiare la definizione di ciò che è un oggetto. Quindi, si possono cambiare queste funzioni di conseguenza.
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(){})
);
Se desideri verificare se il prototype
per un object
viene solo Object
. Filtra String
, Number
, Array
, Arguments
, etc.
function isObject (n) {
return Object.prototype.toString.call(n) === '[object Object]';
}
O come una funzione freccia a espressione singola (ES6 +)
const isObject = n => Object.prototype.toString.call(n) === '[object Object]'
return Object.prototype.toString.call(n) === '[object Object]'
null
assegno, perchéObject.prototype.toString.call(null) === '[object Null]'
var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true
var b ={a: 1}
b instanceof Object //true
b instanceof Array //false
var c = null
c instanceof Object //false
c instanceof Array //false
Mi è stato chiesto di fornire maggiori dettagli. Il modo più pulito e comprensibile per verificare se la nostra variabile è un oggetto è typeof myVar
. Si restituisce una stringa con un tipo (ad esempio "object"
, "undefined"
).
Sfortunatamente anche Array e null hanno un tipo object
. Per prendere solo oggetti reali è necessario controllare la catena di ereditarietà utilizzando l' instanceof
operatore. Eliminerà null, ma Array ha Object nella catena di ereditarietà.
Quindi la soluzione è:
if (myVar instanceof Object && !(myVar instanceof Array)) {
// code for objects
}
/./ instanceof Object //true
Poco tardi ... per "oggetti semplici" (voglio dire, come {'x': 5, 'y': 7}) ho questo piccolo frammento:
function isPlainObject(o) {
return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
false
:(typeof o == 'object');
}
Genera il prossimo output:
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
Funziona sempre per me. If restituirà "true" solo se il tipo di "o" è "object", ma non è null, o array o funzione. :)
lodash ha isPlainObject , che potrebbe essere quello che stanno cercando molti che vengono su questa pagina. Restituisce false quando fornisce una funzione o un array.
_.isObject
quali corrispondenze ciò che JS considera un oggetto. Ma di solito ho bisogno di distinguere tra un oggetto letterale e un array, che è esattamente ciò _.isPlainObject
che mi permette di fare.
Questo funzionerà. È una funzione che restituisce true, false o eventualmente null.
const isObject = obj => obj && obj.constructor && obj.constructor === Object;
console.log(isObject({})); // true
console.log(isObject([])); // false
console.log(isObject(new Function)); // false
console.log(isObject(new Number(123))); // false
console.log(isObject(null)); // null
null
come risultato il test finale anziché false
. Vedi Quando devo apportare modifiche al codice?
Poiché sembra esserci molta confusione su come gestire correttamente questo problema, lascerò i miei 2 centesimi (questa risposta è conforme alle specifiche e produce risultati corretti in tutte le circostanze):
Test per primitivi:
undefined
null
boolean
string
number
function isPrimitive(o){return typeof o!=='object'||null}
Un oggetto non è un primitivo:
function isObject(o){return !isPrimitive(o)}
O in alternativa:
function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}
Test per qualsiasi 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];
}
}());
Test per oggetto escluso: Date
RegExp
Boolean
Number
String
Function
qualsiasi 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];
}
}());
Quando tutto il resto fallisce, io uso questo:
var isObject = function(item) {
return item.constructor.name === "Object";
};
item.constructor === Object
?
null
genera un'eccezioneUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
oa causa di constructor.name
?
La libreria funzionale Ramda ha una meravigliosa funzione per rilevare i tipi di JavaScript.
Parafrasando la funzione completa :
function type(val) {
return val === null ? 'Null' :
val === undefined ? 'Undefined' :
Object.prototype.toString.call(val).slice(8, -1);
}
Ho dovuto ridere quando ho capito quanto fosse semplice e bella la soluzione.
Esempio di utilizzo dalla documentazione Ramda :
R.type({}); //=> "Object"
R.type(1); //=> "Number"
R.type(false); //=> "Boolean"
R.type('s'); //=> "String"
R.type(null); //=> "Null"
R.type([]); //=> "Array"
R.type(/[A-z]/); //=> "RegExp"
R.type(() => {}); //=> "Function"
R.type(undefined); //=> "Undefined"
Dopo aver letto e provare un sacco di implementazioni, ho notato che pochissime persone cercano di verificare la presenza di valori come JSON
, Math
, document
o oggetti con catene prototipo più di 1 punto.
Invece di controllare la typeof
nostra variabile e quindi eliminare i casi limite, ho pensato che sarebbe meglio se il controllo fosse mantenuto il più semplice possibile per evitare di dover refactoring quando sono state aggiunte nuove primitive o oggetti nativi che registrano come typeof
'oggetto '.
Dopotutto, l' typeof
operatore ti dirà se qualcosa è un oggetto per JavaScript , ma la definizione di JavaScript di un oggetto è troppo ampia per la maggior parte degli scenari del mondo reale (ad es typeof null === 'object'
.). Di seguito è una funzione che determina se la variabile v
è un oggetto essenzialmente ripetendo due controlli:
v
è '[object Object]'
. v
viene sostituito con il prototipo successivo nella catena con v = Object.getPrototypeOf(v)
, ma anche valutato direttamente dopo. Quando il nuovo valore di v
è null
, significa che ogni prototipo incluso il prototipo di root (che potrebbe benissimo essere stato l' unico prototipo all'interno della catena) ha superato il controllo nel ciclo while e possiamo restituire vero. Altrimenti, inizia una nuova iterazione.function isObj (v) {
while ( Object.prototype.toString.call(v) === '[object Object]')
if ((v = Object.getPrototypeOf(v)) === null)
return true
return false
}
console.log('FALSE:')
console.log('[] -> ', isObj([]))
console.log('null -> ', isObj(null))
console.log('document -> ', isObj(document))
console.log('JSON -> ', isObj(JSON))
console.log('function -> ', isObj(function () {}))
console.log('new Date() -> ', isObj(new Date()))
console.log('RegExp -> ', isObj(/./))
console.log('TRUE:')
console.log('{} -> ', isObj({}))
console.log('new Object() -> ', isObj(new Object()))
console.log('new Object(null) -> ', isObj(new Object(null)))
console.log('new Object({}) -> ', isObj(new Object({foo: 'bar'})))
console.log('Object.prototype -> ', isObj(Object.prototype))
console.log('Object.create(null) -> ', isObj(Object.create(null)))
console.log('Object.create({}) -> ', isObj(Object.create({foo: 'bar'})))
console.log('deep inheritance -> ', isObj(Object.create(Object.create({foo: 'bar'}))))
if(typeof value === 'object' && value.constructor === Object)
{
console.log("This is an object");
}
value
è null
questo genererà un errore ...
false
per l'oggetto Object.assign({}, {constructor: null})
.
È una vecchia domanda, ma ho pensato di lasciarlo qui. La maggior parte delle persone sta verificando se la variabile sta {}
significando un valore-chiave associato e non qual è il costrutto di sottolineatura che JavaScript sta usando per una determinata cosa, perché, per essere onesti, quasi tutto in JavaScript è un oggetto. Quindi togliendolo di mezzo. Se fate...
let x = function() {}
typeof x === 'function' //true
x === Object(x) // true
x = []
x === Object(x) // true
// also
x = null
typeof null // 'object'
Il più delle volte ciò che vogliamo è sapere se abbiamo un oggetto risorsa da un'API o la nostra chiamata al database restituita dall'ORM. Possiamo quindi verificare se non è un Array
, non null
è, non 'function'
è un tipo di, ed è unObject
// To account also for new Date() as @toddmo pointed out
x instanceof Object && x.constructor === Object
x = 'test' // false
x = 3 // false
x = 45.6 // false
x = undefiend // false
x = 'undefiend' // false
x = null // false
x = function(){} // false
x = [1, 2] // false
x = new Date() // false
x = {} // true
true
pernew Date()
new Date()
Quello che mi piace usare è questo
function isObject (obj) {
return typeof(obj) == "object"
&& !Array.isArray(obj)
&& obj != null
&& obj != ""
&& !(obj instanceof String) }
Penso che nella maggior parte dei casi una data debba passare il controllo come oggetto, quindi non filtrare le date
ho trovato un "nuovo" modo di fare proprio questo tipo di controllo del tipo da questa domanda SO: Perché instanceof restituisce false per alcuni letterali?
da ciò, ho creato una funzione per il controllo del tipo come segue:
function isVarTypeOf(_var, _type){
try {
return _var.constructor === _type;
} catch(ex) {
return false; //fallback for null or undefined
}
}
allora puoi semplicemente fare:
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
questo è testato su Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43
modifica:
se si desidera anche verificare se una variabile è nulla o non definita, è possibile utilizzare questa invece:
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
aggiornamento dal commento di inanc: sfida accettata: D
se vuoi perdere oggetti di confronto puoi provare in questo modo:
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
}
}
}
in questo modo, puoi fare proprio come il commento di Inanc:
isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true
o
Foo = function(){};
Bar = function(){};
isVarTypeOf(new Foo(), Object); // returns false
isVarTypeOf(new Foo(), Object, true); // returns true
isVarTypeOf(new Bar(), Foo, true); // returns false
isVarTypeOf(new Bar(), Bar, true); // returns true
isVarTypeOf(new Bar(), Bar); // returns true
instanceof
per verificare la presenza di oggetti. Tuttavia, questa non è una scienza esatta.
new Foo()
restituisce un Foo
oggetto, lo stesso che new String()
restituisce un String
oggetto o new Date()
restituisce un Date
oggetto, puoi Foo = function(){}; isVarTypeOf(new Foo(), Foo);
anche fare
null
tratta di un oggetto).