Controlla se l'oggetto è un oggetto jQuery


602

Esiste un modo rapido per verificare se un oggetto è un oggetto jQuery o un oggetto JavaScript nativo?

esempio:

var o = {};
var e = $('#element');

function doStuff(o) {
    if (o.selector) {
        console.log('object is jQuery');
    }
}

doStuff(o);
doStuff(e);

ovviamente, il codice sopra funziona ma non è sicuro. Potresti potenzialmente aggiungere una chiave di selezione oall'oggetto e ottenere lo stesso risultato. Esiste un modo migliore per assicurarsi che l'oggetto sia effettivamente un oggetto jQuery?

Qualcosa in linea con (typeof obj == 'jquery')


3
A partire da jQuery 3.0 questo non è sicuramente un modo corretto per verificare se un oggetto è un oggetto jQuery perché la selectorproprietà è stata deprecata molto tempo fa e rimossa in 3.0. Anche nelle versioni precedenti, un oggetto jQuery può avere una stringa di selezione vuota, ad esempio $(window)non ha un selettore. Usa instanceofinvece.
Dave Methvin,

Risposte:


878

Puoi usare l' instanceofoperatore:

if (obj instanceof jQuery){
    console.log('object is jQuery');
}

Spiegazione : la jQueryfunzione (aka $) è implementata come funzione di costruzione . Le funzioni del costruttore devono essere richiamate con il newprefisso.

Quando chiami $(foo), internamente jQuery lo traduce in new jQuery(foo)1 . JavaScript procede all'inizializzazione thisall'interno della funzione di costruzione per puntare a una nuova istanza di jQuery, impostando le sue proprietà su quelle trovate su jQuery.prototype(aka jQuery.fn). Così, si ottiene un newoggetto in cui instanceof jQueryè true.


1 In realtà è new jQuery.prototype.init(foo): la logica del costruttore è stata scaricata su un'altra funzione del costruttore chiamata init, ma il concetto è lo stesso.


8
Quindi vuoi dire if (obj instanceof jQuery){...}?
Nigel Angel,

2
@NigelAngel: Sì, questo è ciò che intende :)
ChaseMoskal,

12
Questo non funziona in caso di più istanze jQuery su una pagina.
Georgii Ivankin,

5
@CrescentFresh Voglio dire se ho $ nel mio spazio dei nomi corrente che punta a jQuery2 e ho un oggetto dallo spazio dei nomi esterno (dove $ è jQuery1) di quanto non ho modo di usare instanceof per verificare se questo oggetto è un oggetto jQuery.
Georgii Ivankin,

6
Se non si è sicuri che jQuery sia caricato al momento dell'istruzione if, è possibile estendere il controllo in typeof jQuery === 'function' && obj instanceof jQueryquanto jQuerynon è necessario dichiararlo affinché l' typeofoperatore funzioni senza generare un errore.
Patrick Roberts,

105

È inoltre possibile utilizzare la proprietà .jquery come descritto qui: http://api.jquery.com/jquery-2/

var a = { what: "A regular JS object" },
b = $('body');

if ( a.jquery ) { // falsy, since it's undefined
    alert(' a is a jQuery object! ');    
}

if ( b.jquery ) { // truthy, since it's a string
    alert(' b is a jQuery object! ');
}

12
Come ha sottolineato David nella domanda, controllare una proprietà di una variabile il cui valore potrebbe essere nullo (cioè se "a" o "b" fossero nulli) non è sicuro (genererà un TypeError). L'uso di "b instanceof jQuery" è migliore.
rstackhouse,

23
In questo modo funziona se jQuery non è caricato, mentre b instanceof jQuerygenera un ReferenceError se jQuery non è disponibile nella pagina. Entrambi gli approcci sono utili in diversi casi.
Nate

Più efficiente forse, ma ancora non sicuro. Potrebbe richiedere try ... catch, in particolare in oldIE.
ClarkeyBoy,

Nei casi in cui è possibile che jQuery non sia caricato, è possibile utilizzareif ((typeof jQuery !== 'undefined') && (obj instanceof jQuery)) {...
Harry Pehkonen,

Questo non è un buon esempio ... molto probabilmente asarebbe un nodo DOM, come document.bodye poi, teoricamente, c'è una possibilità che la jquerychiave sia in qualche modo arrivata in cima alla catena di quel nodo.
vsync,


26

Il modo migliore per verificare l'istanza di un oggetto è tramite l' istanza dell'operatore o con il metodo isPrototypeOf () che controlla se il prototipo di un oggetto si trova nella catena di prototipi di un altro oggetto.

obj instanceof jQuery;
jQuery.prototype.isPrototypeOf(obj);

Ma a volte potrebbe fallire nel caso di più istanze jQuery su un documento. Come menzionato da @Georgiy Ivankin:

se ho $nel mio attuale spazio dei nomi che punta a jQuery2e ho un oggetto dallo spazio dei nomi esterno (dove si $trova jQuery1), allora non ho modo di usare instanceofper verificare se quell'oggetto è un jQueryoggetto

Un modo per ovviare a questo problema è alias dell'oggetto jQuery in una chiusura o IIFE

//aliases jQuery as $
(function($, undefined) {
    /*... your code */

    console.log(obj instanceof $);
    console.log($.prototype.isPrototypeOf(obj));

    /*... your code */
}(jQuery1));
//imports jQuery1

Un altro modo per ovviare a questo problema è informarsi sulla jqueryproprietàobj

'jquery' in obj

Tuttavia, se si tenta di eseguire tale controllo con valori primitivi, verrà generato un errore, quindi è possibile modificare il controllo precedente assicurandosi objdi essere unObject

'jquery' in Object(obj)

Sebbene il modo precedente non sia il più sicuro (puoi creare la 'jquery'proprietà in un oggetto), possiamo migliorare la validazione lavorando con entrambi gli approcci:

if (obj instanceof jQuery || 'jquery' in Object(obj)) { }

Il problema qui è che qualsiasi oggetto può definire una proprietà jquerycome propria, quindi un approccio migliore sarebbe chiedere nel prototipo e assicurarsi che l'oggetto non sia nulloundefined

if (obj && (obj instanceof jQuery || obj.constructor.prototype.jquery)) { }

A causa coercizione , la ifdichiarazione farà cortocircuito valutando l' &&operatore quando objè qualsiasi falsy valori ( null, undefined, false, 0, ""), e quindi procede ad eseguire le altre convalide.

Finalmente possiamo scrivere una funzione di utilità:

function isjQuery(obj) {
  return (obj && (obj instanceof jQuery || obj.constructor.prototype.jquery));
}

Diamo un'occhiata a: Operatori logici e verità / falsità


In che modo migliora la sicurezza? Gli oggetti non jQuery con una proprietà jquery verrebbero comunque erroneamente rilevati. Non vedo neanche cos'altro potrebbe migliorare "utilizzando" entrambi gli approcci.
Gui Prá,

questo è un modo semplice per verificare se un oggetto è un oggetto jQuery, se per qualsiasi motivo sospetti che qualcuno stia creando oggetti con proprietà come jquery , puoi creare un validatore più robusto, ovvero verificare la presenza di proprietà nel prototipo: myObj .constructor.prototype.jquery o meglio ancora, puoi usare la funzione Object.prototype.isPrototypeOf ()
jherax

1
Se uno ||qualsiasi di quelli con a 'jquery' in Object(obj), tuttavia, si esaurisce, perché non impedisce agli oggetti non jQuery con quella proprietà di passare la verifica. Credo che il controllo di quella proprietà nel prototipo migliori la situazione, però. Forse dovresti aggiungerlo alla tua risposta! Non credo che nessun'altra risposta menzioni questa possibilità :)
Gui Prá

1
non è obj.__proto__.jqueryinvece obj.constructor.prototype.jqueryabbastanza? solo un po 'corto :)
Axel,

1
@Axel sì, funziona troppo :). L'ho usato constructor.prototypeperchéobj dovrebbe essere un'istanza del costruttore, cioè jQuery. D'altra parte __proto__è disponibile per qualsiasi tipo di oggetto.
jherax,

3
return el instanceof jQuery ? el.size() > 0 : (el && el.tagName);

Per verificare la presenza di un elemento DOM, utilizzare meglio la nodeTypeproprietà e garantire la booleanrestituzione di un valore, è possibile utilizzare la doppia negazione!!(el && el.nodeType)
jherax,

3

Tuttavia, esiste un altro modo per controllare l'oggetto in jQuery.

jQuery.type(a); //this returns type of variable.

Ho fatto un esempio per capire le cose, jsfiddle link


2

Per coloro che vogliono sapere se un oggetto è un oggetto jQuery senza aver installato jQuery, il seguente frammento dovrebbe fare il lavoro:

function isJQuery(obj) {
  // Each jquery object has a "jquery" attribute that contains the version of the lib.
  return typeof obj === "object" && obj && obj["jquery"];
}

1

Puoi verificare se l'oggetto è prodotto da JQuery con la jqueryproprietà:

myObject.jquery // 3.3.1

=> restituisce il numero della versione di JQuery se l'oggetto prodotto da JQuery. => altrimenti, ritornaundefined


-9
var elArray = [];
var elObjeto = {};

elArray.constructor == Array //TRUE
elArray.constructor == Object//TALSE

elObjeto.constructor == Array//FALSE
elObjeto.constructor == Object//TRUE

11
I dump di codice senza spiegazione sono raramente utili. Ti preghiamo di considerare di aggiungere un po 'di contesto alla tua risposta.
Chris,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.