Periksa apakah objek adalah objek jQuery

602

Apakah ada cara cepat untuk memeriksa apakah suatu objek adalah objek jQuery atau objek JavaScript asli?

contoh:

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

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

doStuff(o);
doStuff(e);

jelas, kode di atas berfungsi tetapi tidak aman. Anda berpotensi menambahkan kunci pemilih ke oobjek dan mendapatkan hasil yang sama. Apakah ada cara yang lebih baik untuk memastikan bahwa objek tersebut sebenarnya adalah objek jQuery?

Sesuatu yang sejalan (typeof obj == 'jquery')

David Hellsing
sumber
3
Pada jQuery 3.0 ini jelas bukan cara yang benar untuk memeriksa objek yang menjadi objek jQuery karena selectorproperti sudah lama ditinggalkan dan dihapus pada 3.0. Bahkan dalam versi sebelumnya, objek jQuery dapat memiliki string pemilih kosong, misalnya $(window)tidak memiliki pemilih. Gunakan instanceofsebagai gantinya.
Dave Methvin

Jawaban:

878

Anda dapat menggunakan instanceofoperator:

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

Penjelasan : jQueryfungsi (alias $) diimplementasikan sebagai fungsi konstruktor . Fungsi konstruktor harus dipanggil dengan newawalan.

Saat Anda menelepon $(foo), secara internal jQuery menerjemahkannya ke new jQuery(foo)1 . JavaScript melanjutkan untuk menginisialisasi thisdi dalam fungsi konstruktor untuk menunjuk ke instance baru jQuery, mengatur properti itu ke yang ditemukan di jQuery.prototype(alias jQuery.fn). Dengan demikian, Anda mendapatkan newobjek di mana instanceof jQueryadalah true.


1 Sebenarnya new jQuery.prototype.init(foo): logika konstruktor telah diturunkan ke fungsi konstruktor lain yang disebut init, tetapi konsepnya sama.

Crescent Fresh
sumber
8
Jadi maksudmu if (obj instanceof jQuery){...}?
Nigel Angel
2
@NigelAngel: Yup, itu yang dia maksudkan :)
ChaseMoskal
12
Ini tidak berfungsi jika ada beberapa instance jQuery pada halaman.
Georgii Ivankin
5
@CrescentFresh Maksud saya jika saya memiliki $ di namespace saya saat ini menunjuk ke jQuery2 dan saya memiliki objek dari namespace luar (di mana $ adalah jQuery1) daripada saya tidak memiliki cara untuk menggunakan instanceof untuk memeriksa apakah objek ini adalah objek jQuery.
Georgii Ivankin
6
Jika Anda tidak yakin apakah jQuery dimuat pada saat pernyataan if, Anda dapat memperpanjang pemeriksaan typeof jQuery === 'function' && obj instanceof jQuerykarena jQuerytidak harus dideklarasikan agar typeofoperator dapat bekerja tanpa membuat kesalahan.
Patrick Roberts
105

Anda juga dapat menggunakan properti .jquery seperti dijelaskan di sini: 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
sumber
12
Seperti yang ditunjukkan David dalam pertanyaan, memeriksa properti variabel yang nilainya bisa nol (yaitu jika "a" atau "b" adalah nol) tidak aman (itu akan melempar TypeError). Menggunakan "b instanceof jQuery" lebih baik.
rstackhouse
23
Cara ini berfungsi jika jQuery tidak dimuat, sedangkan b instanceof jQuerymelempar ReferenceError jika jQuery tidak tersedia di halaman. Kedua pendekatan ini bermanfaat dalam berbagai kasus.
Nate
Lebih efisien mungkin, tetapi masih belum aman. Mungkin diperlukan try ... catch, khususnya di oldIE.
ClarkeyBoy
Dalam kasus di mana dimungkinkan jQuery tidak dimuat, Anda dapat menggunakanif ((typeof jQuery !== 'undefined') && (obj instanceof jQuery)) {...
Harry Pehkonen
Itu bukan contoh yang baik .. lebih mungkin aakan menjadi simpul DOM, seperti document.bodydan kemudian, secara teoritis ada kemungkinan jquerykunci entah bagaimana menjadi ontop dari rantai simpul itu.
vsync
30

Lihat instance operator.

var isJqueryObject = obj instanceof jQuery
Corey Sunwold
sumber
26

Cara terbaik untuk memeriksa instance objek adalah melalui instanceof operator atau dengan metode isPrototypeOf () yang memeriksa apakah prototipe objek berada dalam rantai prototipe objek lain.

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

Tetapi kadang-kadang mungkin gagal dalam kasus beberapa contoh jQuery pada dokumen. Seperti yang disebutkan @Georgiy Ivankin:

jika saya memiliki $di saya saat namespace menunjuk ke jQuery2dan saya memiliki objek dari namespace luar (di mana $adalah jQuery1) maka saya tidak punya cara untuk menggunakan instanceofuntuk memeriksa apakah benda adalah jQueryobjek

Salah satu cara untuk mengatasi masalah itu adalah dengan aliasing objek jQuery dalam penutupan atau IIFE

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

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

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

Cara lain untuk mengatasi masalah itu adalah dengan menanyakan jqueryproperti diobj

'jquery' in obj

Namun, jika Anda mencoba melakukan pengecekan dengan nilai-nilai primitif, itu akan menimbulkan kesalahan, sehingga Anda dapat memodifikasi pemeriksaan sebelumnya dengan memastikan objmenjadiObject

'jquery' in Object(obj)

Meskipun cara sebelumnya bukan yang paling aman (Anda dapat membuat 'jquery'properti di objek), kami dapat meningkatkan validasi dengan bekerja dengan kedua pendekatan:

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

Masalahnya di sini adalah bahwa objek apa pun dapat mendefinisikan properti jquerysebagai miliknya, jadi pendekatan yang lebih baik adalah dengan bertanya dalam prototipe, dan memastikan bahwa objek tersebut tidak nullatauundefined

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

Karena paksaan , yang ifpernyataan akan membuat hubungan pendek dengan mengevaluasi &&operator saat objini salah satu falsy nilai ( null, undefined, false, 0, ""), dan kemudian mulai melakukan validasi lainnya.

Akhirnya kita dapat menulis fungsi utilitas:

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

Mari kita lihat: Operator Logika dan kebenaran / kepalsuan

jherax
sumber
Bagaimana cara meningkatkan keamanan? Objek non-jQuery dengan properti jquery masih akan salah terdeteksi. Saya tidak melihat apa lagi yang menggunakan kedua pendekatan yang mungkin "membaik".
Gui Prá
ini adalah cara mudah untuk memeriksa apakah suatu objek adalah objek jQuery, jika karena alasan apa pun Anda mencurigai seseorang membuat objek dengan properti seperti jquery , maka Anda dapat membuat validator yang lebih kuat, yaitu memeriksa properti dalam prototipe: myObj .constructor.prototype.jquery atau yang lebih baik lagi, Anda dapat menggunakan fungsi Object.prototype.isPrototypeOf ()
jherax
1
Jika Anda ||salah satu dari itu dengan 'jquery' in Object(obj),, itu akan mengalir, karena itu tidak akan mencegah objek non-jQuery dengan properti itu melewati verifikasi. Saya percaya memeriksa properti itu dalam prototipe meningkatkan situasi. Mungkin Anda harus menambahkan itu ke jawaban Anda! Saya tidak berpikir ada jawaban lain di sini yang menyebutkan kemungkinan itu :)
Gui Prá
1
bukankah obj.__proto__.jquerybukannya obj.constructor.prototype.jquerycukup? hanya agak pendek :)
Axel
1
@Axel ya, itu berfungsi juga :). Saya menggunakan constructor.prototypekarena objseharusnya menjadi contoh dari konstruktor, yaitu jQuery. Di sisi lain __proto__tersedia untuk semua jenis objek.
jherax
3
return el instanceof jQuery ? el.size() > 0 : (el && el.tagName);
Johnchou
sumber
Untuk memeriksa elemen DOM, menggunakan nodeTypeproperti yang lebih baik , dan untuk memastikan booleannilai dikembalikan, Anda dapat menggunakan negasi ganda!!(el && el.nodeType)
jherax
3

Namun, ada satu lagi cara untuk memeriksa objek di jQuery.

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

Saya telah membuat contoh untuk memahami hal-hal, tautan jsfiddle

Shaunak Shukla
sumber
2

Bagi mereka yang ingin tahu apakah suatu objek adalah objek jQuery tanpa menginstal jQuery, cuplikan berikut harus melakukan pekerjaan:

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
sumber
1

Anda dapat memeriksa apakah objek tersebut diproduksi oleh JQuery dengan jqueryproperti:

myObject.jquery // 3.3.1

=> mengembalikan nomor versi JQuery jika objek yang dihasilkan oleh JQuery. => sebaliknya, ia kembaliundefined

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

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

elObjeto.constructor == Array//FALSE
elObjeto.constructor == Object//TRUE
Gabriel Seg
sumber
11
Kesedihan kode tanpa penjelasan jarang bermanfaat. Silakan pertimbangkan untuk menambahkan beberapa konteks pada jawaban Anda.
Chris