Compruebe si el objeto es un objeto jQuery

602

¿Existe una forma rápida de verificar si un objeto es un objeto jQuery o un objeto JavaScript nativo?

ejemplo:

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

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

doStuff(o);
doStuff(e);

obviamente, el código anterior funciona pero no es seguro. Potencialmente, podría agregar una tecla selectora al oobjeto y obtener el mismo resultado. ¿Hay una mejor manera de asegurarse de que el objeto sea realmente un objeto jQuery?

Algo en línea con (typeof obj == 'jquery')

David Hellsing
fuente
3
A partir de jQuery 3.0, esta definitivamente no es una forma correcta de verificar si un objeto es un objeto jQuery porque la selectorpropiedad fue obsoleta hace mucho tiempo y se eliminó en 3.0. Incluso en versiones anteriores, un objeto jQuery puede tener una cadena de selector vacía, por ejemplo, $(window)no tiene selector. Usar en su instanceoflugar.
Dave Methvin

Respuestas:

878

Puedes usar el instanceofoperador:

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

Explicación : la jQueryfunción (aka $) se implementa como una función constructora . Las funciones de constructor deben llamarse con el newprefijo.

Cuando llamas $(foo), internamente jQuery traduce esto a new jQuery(foo)1 . JavaScript procede a inicializarse thisdentro de la función constructora para apuntar a una nueva instancia de jQuery, estableciendo sus propiedades a las que se encuentran en jQuery.prototype(aka jQuery.fn). Por lo tanto, obtienes un newobjeto donde instanceof jQueryestá true.


1 En realidad es new jQuery.prototype.init(foo): la lógica del constructor se ha descargado a otra función de constructor llamada init, pero el concepto es el mismo.

Creciente Fresco
fuente
8
¿Entonces quieres decir if (obj instanceof jQuery){...}?
Nigel Angel
2
@NigelAngel: Sí, eso es lo que quiere decir :)
ChaseMoskal
12
Esto no funciona en caso de múltiples instancias de jQuery en una página.
Georgii Ivankin
55
@CrescentFresh Quiero decir que si tengo $ en mi espacio de nombres actual apuntando a jQuery2 y tengo un objeto del espacio de nombres externo (donde $ es jQuery1), entonces no tengo forma de usar instanceof para verificar si este objeto es un objeto jQuery.
Georgii Ivankin
66
Si no está seguro de si jQuery se carga en el momento de la sentencia if, se puede extender el cheque para ser typeof jQuery === 'function' && obj instanceof jQueryya jQueryno tiene que ser declarado para que el typeofoperador trabaje sin lanzar un error.
Patrick Roberts
105

También puede usar la propiedad .jquery como se describe aquí: 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! ');
}
mt81
fuente
12
Como David señaló en la pregunta, verificar una propiedad de una variable cuyo valor podría ser nulo (es decir, si "a" o "b" fueran nulos) no es seguro (arrojará un TypeError). Usar "b instanceof jQuery" es mejor.
rstackhouse
23
De esta manera funciona si jQuery no está cargado, mientras que b instanceof jQueryarroja un ReferenceError si jQuery no está disponible en la página. Ambos enfoques son útiles en diferentes casos.
Nate
Quizás más eficiente, pero aún no es seguro. Puede requerir try ... catch, particularmente en oldIE.
ClarkeyBoy
En los casos en que sea posible que jQuery no esté cargado, puede usarif ((typeof jQuery !== 'undefined') && (obj instanceof jQuery)) {...
Harry Pehkonen el
Ese no es un buen ejemplo ... es más probable aque sea un nodo DOM, document.bodyy luego, teóricamente, existe la posibilidad de que la jqueryclave de alguna manera llegue a estar en la parte superior de la cadena de ese nodo.
vsync
30

Echa un vistazo a la instancia de operador.

var isJqueryObject = obj instanceof jQuery
Corey Sunwold
fuente
26

La mejor manera de verificar la instancia de un objeto es a través del operador instanceof o con el método isPrototypeOf () que inspecciona si el prototipo de un objeto está en la cadena de prototipos de otro objeto.

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

Pero a veces puede fallar en el caso de varias instancias de jQuery en un documento. Como @Georgiy Ivankin mencionó:

si tengo $en mi espacio de nombres actual apuntando jQuery2y tengo un objeto del espacio de nombres externo (donde $está jQuery1), entonces no tengo forma de usarlo instanceofpara verificar si ese objeto es un jQueryobjeto

Una forma de superar ese problema es aliasar el objeto jQuery en un cierre o IIFE

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

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

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

Otra forma de superar ese problema es preguntando la jquerypropiedad enobj

'jquery' in obj

Sin embargo, si intenta realizar esa comprobación con valores primitivos, arrojará un error, por lo que puede modificar la comprobación anterior asegurándose objde ser unObject

'jquery' in Object(obj)

Aunque la forma anterior no es la más segura (puede crear la 'jquery'propiedad en un objeto), podemos mejorar la validación trabajando con ambos enfoques:

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

El problema aquí es que cualquier objeto puede definir una propiedad jquerycomo propia, por lo que un mejor enfoque sería preguntar en el prototipo y asegurarse de que el objeto no nullseaundefined

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

Debido a la coacción , la ifdeclaración hará cortocircuito mediante la evaluación del &&operador cuando objes cualquiera de los Falsy valores ( null, undefined, false, 0, ""), y luego procede a realizar las validaciones otros.

Finalmente podemos escribir una función de utilidad:

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

Echemos un vistazo a: Operadores lógicos y verdadero / falso

jherax
fuente
Sin embargo, ¿cómo mejora eso la seguridad? Los objetos que no son jQuery con una propiedad jquery aún se detectarían incorrectamente. No veo qué otra cosa usando ambos enfoques podría "mejorar", tampoco.
Gui Prá
esta es una manera fácil de verificar si un objeto es un objeto jQuery, si por alguna razón sospecha que alguien está creando objetos con propiedades como jquery , puede crear un validador más robusto, es decir, verificar las propiedades en el prototipo: myObj .constructor.prototype.jquery o mejor aún, puede usar la función Object.prototype.isPrototypeOf ()
jherax
1
Si ||algo de eso con un 'jquery' in Object(obj), sin embargo, se va a drenar, porque no evitará que los objetos que no son jQuery con esa propiedad pasen la verificación. Sin embargo, creo que verificar esa propiedad en el prototipo mejora la situación. ¡Quizás deberías agregar eso a tu respuesta! No creo que ninguna otra respuesta aquí mencione esa posibilidad :)
Gui Prá
1
no es en obj.__proto__.jquerylugar de obj.constructor.prototype.jquerysuficiente? solo un poco corto :)
Axel
1
@Axel sí, también funciona :). Solía constructor.prototypeporque objse supone que es una instancia del constructor, es decir jQuery. Por otro lado __proto__está disponible para cualquier tipo de objeto.
jherax
3
return el instanceof jQuery ? el.size() > 0 : (el && el.tagName);
johnchou
fuente
Para verificar si hay un elemento DOM, usar mejor la nodeTypepropiedad y garantizar booleanque se devuelva un valor, puede usar la negación doble!!(el && el.nodeType)
jherax
3

Sin embargo, hay una forma más de verificar el objeto en jQuery.

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

He hecho un ejemplo para entender cosas, enlace jsfiddle

Shaunak Shukla
fuente
2

Para aquellos que desean saber si un objeto es un objeto jQuery sin tener jQuery instalado, el siguiente fragmento debe hacer el trabajo:

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

Puede verificar si el objeto es producido por JQuery con la jquerypropiedad:

myObject.jquery // 3.3.1

=> devuelve el número de la versión de JQuery si el objeto producido por JQuery. => de lo contrario, devuelveundefined

Jérôme-Victor Toulouse
fuente
-9
var elArray = [];
var elObjeto = {};

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

elObjeto.constructor == Array//FALSE
elObjeto.constructor == Object//TRUE
Gabriel Seg
fuente
11
Los volcados de código sin explicación rara vez son útiles. Considere agregar algo de contexto a su respuesta.
Chris