Sprawdź, czy obiekt jest obiektem jQuery


601

Czy istnieje szybki sposób sprawdzenia, czy obiekt jest obiektem jQuery czy rodzimym obiektem JavaScript?

przykład:

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

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

doStuff(o);
doStuff(e);

oczywiście powyższy kod działa, ale nie jest bezpieczny. Możesz potencjalnie dodać klawisz wyboru do oobiektu i uzyskać ten sam wynik. Czy istnieje lepszy sposób upewnienia się, że obiekt faktycznie jest obiektem jQuery?

Coś zgodnego z (typeof obj == 'jquery')


3
Począwszy od jQuery 3.0, zdecydowanie nie jest to poprawny sposób sprawdzania, czy obiekt jest obiektem jQuery, ponieważ selectorwłaściwość została dawno przestarzała i usunięta w 3.0. Nawet we wcześniejszych wersjach obiekt jQuery może mieć pusty ciąg selektora, na przykład $(window)nie ma selektora. Użyj instanceofzamiast tego.
— Dave Methvin

Odpowiedzi:


878

Możesz użyć instanceofoperatora:

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

Objaśnienie : jQueryfunkcja (aka $) jest zaimplementowana jako funkcja konstruktora . Funkcje konstruktora należy wywoływać z newprefiksem.

Kiedy dzwonisz $(foo), wewnętrznie jQuery tłumaczy to na new jQuery(foo)1 . JavaScript przechodzi do inicjalizacjithis wewnątrz funkcji konstruktora, aby wskazać nowe wystąpienie jQuery, ustawiając jego właściwości na właściwości znalezione na jQuery.prototype(aka jQuery.fn). W ten sposób otrzymujesz newobiekt gdzie instanceof jQueryjest true.


1 To jest właściwienew jQuery.prototype.init(foo) : logika konstruktora została przeniesiona do innej wywoływanej funkcji konstruktora init, ale koncepcja jest taka sama.


8
Masz na myśli if (obj instanceof jQuery){...}?
— Nigel Angel,

2
@NigelAngel: Tak, o to mu chodzi :)
— ChaseMoskal

12
Nie działa to w przypadku wielu instancji jQuery na stronie.
— Georgii Ivankin

5
@CrescentFresh Mam na myśli, jeśli mam $ w mojej bieżącej przestrzeni nazw wskazującej na jQuery2 i mam obiekt z zewnętrznej przestrzeni nazw (gdzie $ to jQuery1) niż nie mam możliwości użycia instanceof do sprawdzenia, czy ten obiekt jest obiektem jQuery.
— Georgii Ivankin

6
Jeśli nie jesteś pewien, czy jQuery jest ładowany w czasie if, można wydłużyć sprawdź, typeof jQuery === 'function' && obj instanceof jQueryponieważ jQuerynie muszą być zadeklarowane w porządku dla typeofoperatora do pracy bez rzuca błąd.
— Patrick Roberts,

105

Możesz także użyć właściwości .jquery, jak opisano tutaj: 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
Jak zauważył David w pytaniu, sprawdzanie właściwości zmiennej, której wartość może być zerowa (tj. Jeśli „a” lub „b” są zerowe), nie jest bezpieczne (spowoduje wygenerowanie błędu TypeError). Użycie „b instanceof jQuery” jest lepsze.
— rstackhouse

23
Ten sposób działa, jeśli jQuery nie jest załadowany, natomiast b instanceof jQueryzgłasza błąd ReferenceError, jeśli jQuery nie jest dostępny na stronie. Oba podejścia są przydatne w różnych przypadkach.
— Nate

Być może bardziej wydajny, ale nadal nie jest bezpieczny. Może to wymagać try ... catch, szczególnie w oldIE.
— ClarkeyBoy

W przypadkach, w których możliwe jest, że jQuery nie jest załadowany, możesz użyćif ((typeof jQuery !== 'undefined') && (obj instanceof jQuery)) {...
— Harry Pehkonen

To nie jest tak dobry przykład .. bardziej prawdopodobne, aże byłby to węzeł DOM, document.bodya wtedy teoretycznie istnieje szansa, że jqueryklucz jakoś pojawił się na łańcuchu tego węzła.
— vsync


26

Najlepszym sposobem sprawdzenia wystąpienia obiektu jest operator instanceof lub metoda to ProtrotOf (), która sprawdza, czy prototyp obiektu znajduje się w łańcuchu prototypów innego obiektu.

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

Ale czasami może się nie powieść w przypadku wielu instancji jQuery w dokumencie. Jak wspomniał @Georgiy Ivankin:

jeśli $w mojej bieżącej przestrzeni nazw wskazuję jQuery2i mam obiekt z zewnętrznej przestrzeni nazw (gdzie $jest jQuery1), to nie mam sposobu, aby instanceofsprawdzić, czy ten obiekt jest jQueryobiektem

Jednym ze sposobów rozwiązania tego problemu jest aliasing obiektu jQuery w zamknięciu lub IIFE

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

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

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

Innym sposobem rozwiązania tego problemu jest zapytanie o jquerynieruchomość wobj

'jquery' in obj

Jeśli jednak spróbujesz przeprowadzić sprawdzanie z wartościami pierwotnymi, wygeneruje błąd, więc możesz zmodyfikować poprzednie sprawdzenie, upewniając objsię, żeObject

'jquery' in Object(obj)

Chociaż poprzedni sposób nie jest najbezpieczniejszy (możesz utworzyć 'jquery'właściwość w obiekcie), możemy poprawić sprawdzanie poprawności, pracując z obiema metodami:

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

Problem polega na tym, że każdy obiekt może zdefiniować właściwość jqueryjako własną, dlatego lepszym rozwiązaniem byłoby zapytanie w prototypie i upewnienie się, że obiekt nie jest nulllubundefined

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

Ze względu na przymus The ifstwierdzenie uczyni zwarcie poprzez ocenę &&operatora kiedy objto każdy z falsy wartości ( null, undefined, false, 0,"" ), a następnie przechodzi do wykonywania innych walidacji.

Wreszcie możemy napisać funkcję narzędzia:

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

Spójrzmy na: Operatory logiczne i prawda / fałsz


Jak to jednak poprawia bezpieczeństwo? Obiekty inne niż jQuery z właściwością jquery nadal byłyby źle wykrywane. Nie widzę też, co jeszcze może się przydać przy obu tych podejściach.
— Gui Prá

jest to prosty sposób na sprawdzenie, czy obiekt jest obiektem jQuery, jeśli z jakiegokolwiek powodu podejrzewasz, że ktoś tworzy obiekty o właściwościach takich jak jquery , możesz utworzyć bardziej solidny weryfikator, tj. sprawdzanie właściwości w prototypie: myObj .constructor.prototype.jquery lub jeszcze lepiej, możesz użyć funkcji Object.prototype.isPrototypeOf ()
— jherax

1
Jeśli ||którykolwiek z 'jquery' in Object(obj)nich ma opcję, spowoduje to wyczerpanie, ponieważ nie zapobiegnie przejściu weryfikacji przez obiekty inne niż jQuery z tą właściwością. Uważam jednak, że sprawdzenie tej właściwości w prototypie poprawia sytuację. Może powinieneś dodać to do swojej odpowiedzi! Nie wydaje mi się, żeby inna odpowiedź tutaj wspominała o takiej możliwości :)
— Gui Prá

1
nie wystarczy obj.__proto__.jqueryzamiast obj.constructor.prototype.jquery? tylko trochę krótko :)
— Axel

1
@Axel tak, to też działa :). Użyłem, constructor.prototypeponieważ objma to być instancja konstruktora jQuery. Z drugiej strony __proto__jest dostępny dla każdego rodzaju obiektu.
— jherax

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

Aby sprawdzić element DOM, lepiej użyć nodeTypewłaściwości i upewnić się, że booleanwartość zostanie zwrócona, możesz użyć podwójnej negacji!!(el && el.nodeType)
— jherax

3

Istnieje jednak jeszcze jeden sposób sprawdzenia obiektu w jQuery.

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

Dałem przykład, aby zrozumieć rzeczy, link jsfiddle


2

Dla tych, którzy chcą wiedzieć, czy obiekt jest obiektem jQuery bez zainstalowanego jQuery, następujący fragment kodu powinien wykonać tę pracę:

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

Możesz sprawdzić, czy obiekt jest generowany przez JQuery za pomocą jquerywłaściwości:

myObject.jquery // 3.3.1

=> zwraca numer wersji JQuery, jeśli obiekt utworzony przez JQuery. => w przeciwnym razie zwracaundefined


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

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

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

11
Zrzuty kodu bez wyjaśnienia rzadko są przydatne. Rozważ dodanie kontekstu do swojej odpowiedzi.
— Chris
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.