Verifique se o objeto é um objeto jQuery


602

Existe uma maneira rápida de verificar se um objeto é um objeto jQuery ou um objeto JavaScript nativo?

exemplo:

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

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

doStuff(o);
doStuff(e);

obviamente, o código acima funciona, mas não é seguro. Você pode adicionar uma chave seletora ao oobjeto e obter o mesmo resultado. Existe uma maneira melhor de garantir que o objeto seja realmente um objeto jQuery?

Algo alinhado com (typeof obj == 'jquery')


3
A partir do jQuery 3.0, essa definitivamente não é uma maneira correta de verificar se um objeto é um objeto jQuery porque a selectorpropriedade foi descontinuada há muito tempo e removida no 3.0. Mesmo nas versões anteriores, um objeto jQuery pode ter uma cadeia de seletores vazia, por exemplo $(window), não possui seletor. Use em instanceofvez disso.
18716 Dave Methvin

Respostas:


878

Você pode usar o instanceofoperador:

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

Explicação : a jQueryfunção (aka $) é implementada como uma função construtora . As funções do construtor devem ser chamadas com o newprefixo.

Quando você liga $(foo), internamente, o jQuery traduz isso para new jQuery(foo)1 . O JavaScript passa a inicializar thisdentro da função construtora para apontar para uma nova instância de jQuery, definindo suas propriedades para as encontradas em jQuery.prototype(aka jQuery.fn). Assim, você obtém um newobjeto onde instanceof jQueryestá true.


1 Na verdade, é new jQuery.prototype.init(foo): a lógica do construtor foi transferida para outra função do construtor chamada init, mas o conceito é o mesmo.


8
Então você quer dizer if (obj instanceof jQuery){...}?
Nigel Anjo

2
@NigelAngel: Sim, isso é o que ele quer dizer :)
ChaseMoskal

12
Isso não funciona no caso de várias instâncias do jQuery em uma página.
Georgii Ivankin

5
@CrescentFresh Quero dizer, se eu tiver $ no meu namespace atual apontando para jQuery2 e tiver um objeto externo (onde $ é jQuery1), não tenho como usar instanceof para verificar se esse objeto é um objeto jQuery.
Georgii Ivankin

6
Se você não tiver certeza se o jQuery está carregado no momento da instrução if, você pode estender a verificação, typeof jQuery === 'function' && obj instanceof jQuerypois jQuerynão precisa ser declarada para que o typeofoperador trabalhe sem gerar um erro.
Patrick Roberts

105

Você também pode usar a propriedade .jquery conforme descrito aqui: 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
Como David apontou na pergunta, verificar uma propriedade de uma variável cujo valor possa ser nulo (ou seja, se "a" ou "b" forem nulos) não é seguro (isso gerará um TypeError). Usar "b instanceof jQuery" é melhor.
Rdackhouse

23
Dessa forma, funciona se o jQuery não estiver carregado, enquanto b instanceof jQuerylança um ReferenceError se o jQuery não estiver disponível na página. Ambas as abordagens são úteis em diferentes casos.
Nate

Talvez mais eficiente, mas ainda não seguro. Pode exigir try ... catch, principalmente no oldIE.
ClarkeyBoy

Nos casos em que é possível que jQuery não é carregado, você pode usarif ((typeof jQuery !== 'undefined') && (obj instanceof jQuery)) {...
Harry Pehkonen

Esse não é um exemplo tão bom. O mais provável aseria um nó DOM, assim document.bodycomo, teoricamente, há uma chance de a jquerychave de alguma forma estar no topo da cadeia desse nó.
vsync


26

A melhor maneira de verificar a instância de um objeto é através do instanceof operator ou com o método isPrototypeOf (), que inspeciona se o protótipo de um objeto está na cadeia de protótipos de outro objeto.

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

Mas, às vezes, pode falhar no caso de várias instâncias do jQuery em um documento. Como @Georgiy Ivankin mencionou:

se eu tenho $no meu namespace atual apontando para jQuery2e eu tenho um objeto do namespace externo (onde $está jQuery1), não tenho como usar instanceofpara verificar se esse objeto é um jQueryobjeto

Uma maneira de superar esse problema é aliasing do objeto jQuery em um fechamento ou IIFE

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

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

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

Outra maneira de superar esse problema é consultando a jquerypropriedade emobj

'jquery' in obj

No entanto, se você tentar executar essa verificação com valores primitivos, ocorrerá um erro, para que você possa modificar a verificação anterior, garantindo objumaObject

'jquery' in Object(obj)

Embora a maneira anterior não seja a mais segura (você pode criar a 'jquery'propriedade em um objeto), podemos melhorar a validação trabalhando com as duas abordagens:

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

O problema aqui é que qualquer objeto pode definir uma propriedade jquerycomo própria, portanto, uma abordagem melhor seria perguntar no protótipo e garantir que o objeto não seja nullou nãoundefined

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

Devido à coerção , a ifdeclaração entrará em curto-circuito avaliando o &&operador quando objalguma das Falsas valores (null,undefined,false,0,""), e então começa a executar as outras validações.

Finalmente, podemos escrever uma função utilitária:

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

Vamos dar uma olhada em: Operadores lógicos e verdade / falsidade


Como isso melhora a segurança? Objetos não-jQuery com uma propriedade jquery ainda seriam mal detectados. Também não vejo o que mais usando as duas abordagens "melhore".
Gui Prá 31/01

Essa é uma maneira fácil de verificar se um objeto é um objeto jQuery. Se, por algum motivo, você suspeitar que alguém está criando objetos com propriedades como jquery , poderá criar um validador mais robusto, ou seja, verificar propriedades no protótipo: myObj .constructor.prototype.jquery ou melhor ainda, você pode usar a função Object.prototype.isPrototypeOf ()
jherax

1
No entanto, se você tiver ||um desses 'jquery' in Object(obj)itens, ele será drenado, porque não impedirá que objetos não-jQuery com essa propriedade passem na verificação. Porém, acredito que verificar essa propriedade no protótipo melhora a situação. Talvez você deva adicionar isso à sua resposta! Eu não acho que nenhuma outra resposta aqui mencione essa possibilidade :)
Gui Prá

1
não é, em obj.__proto__.jqueryvez de o obj.constructor.prototype.jquerysuficiente? apenas um pouco curto :)
Axel

1
@ Axel sim, também funciona :). Eu usei constructor.prototypeporque objé suposto ser uma instância do construtor, ou seja jQuery. Por outro lado, __proto__está disponível para qualquer tipo de objeto.
jherax

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

Para verificar se um elemento DOM, a melhor utilização nodeTypeda propriedade, e assegurar um booleanvalor ser devolvido, você pode usar dupla negação!!(el && el.nodeType)
jherax

3

No entanto, há mais uma maneira de verificar o objeto no jQuery.

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

Eu fiz exemplo para entender as coisas, jsfiddle link


2

Para aqueles que desejam saber se um objeto é um objeto jQuery sem ter o jQuery instalado, o seguinte snippet deve fazer o trabalho:

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

Você pode verificar se o objeto é produzido pelo JQuery com a jquerypropriedade:

myObject.jquery // 3.3.1

=> retorna o número da versão do JQuery se o objeto produzido pelo JQuery. => caso contrário, ele retornaundefined


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

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

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

11
Despejos de código sem explicação raramente são úteis. Por favor, considere adicionar algum contexto à sua resposta.
18714 Chris
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.