ตรวจสอบว่าวัตถุเป็นวัตถุ jQuery


601

มีวิธีที่รวดเร็วในการตรวจสอบว่าวัตถุเป็นวัตถุ jQuery หรือวัตถุ JavaScript ดั้งเดิมหรือไม่

ตัวอย่าง:

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

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

doStuff(o);
doStuff(e);

เห็นได้ชัดว่ารหัสข้างต้นใช้งานได้ แต่ไม่ปลอดภัย คุณอาจเพิ่มคีย์ตัวเลือกลงในoวัตถุและรับผลลัพธ์เดียวกัน มีวิธีที่ดีกว่าในการตรวจสอบให้แน่ใจว่าวัตถุเป็นวัตถุ jQuery จริงหรือไม่

สิ่งที่สอดคล้องกับ (typeof obj == 'jquery')


3
ในฐานะของ jQuery 3.0 นี่ไม่ใช่วิธีที่ถูกต้องในการตรวจสอบวัตถุที่เป็นวัตถุ jQuery เนื่องจากselectorคุณสมบัติถูกเลิกใช้มานานแล้วและถูกลบใน 3.0 แม้ในรุ่นก่อนหน้าวัตถุ jQuery สามารถมีสตริงตัวเลือกที่ว่างเปล่าตัวอย่างเช่น$(window)ไม่มีตัวเลือก ใช้instanceofแทน
Dave Methvin

คำตอบ:


878

คุณสามารถใช้instanceofโอเปอเรเตอร์:

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

คำอธิบายที่: jQueryฟังก์ชั่น (aka $) จะดำเนินการเป็นฟังก์ชั่นคอนสตรัค ฟังก์ชันตัวสร้างจะถูกเรียกพร้อมกับส่วนnewนำหน้า

เมื่อคุณโทร$(foo)ภายใน jQuery แปลนี้1new jQuery(foo) จาวาสคริปต์ดำเนินการเพื่อเริ่มต้นthisภายในฟังก์ชั่นคอนสตรัคให้ชี้ไปที่อินสแตนซ์ใหม่ของjQueryการตั้งค่ามันเป็นคุณสมบัติที่พบในjQuery.prototype(aka jQuery.fn) ดังนั้นคุณจะได้รับnewวัตถุที่เป็นinstanceof jQuerytrue


1 จริง ๆ แล้วnew jQuery.prototype.init(foo): คอนสตรัคชันของตรรกะได้ถูกถ่ายลงในฟังก์ชั่นคอนสตรัคเตอร์อื่นที่เรียกว่าinitแต่แนวคิดนั้นเหมือนกัน


8
ดังนั้นคุณหมายถึงif (obj instanceof jQuery){...}อะไร
Nigel Angel

2
@NigelAngel: Yup ว่าเป็นสิ่งที่เขาหมายถึง :)
ChaseMoskal

12
สิ่งนี้ไม่สามารถใช้งานได้ในกรณีที่มี jQuery หลายอินสแตนซ์บนหน้าเว็บ
Georgii Ivankin

5
@CrescentFresh ฉันหมายความว่าถ้าฉันมี $ ใน namespace ปัจจุบันของฉันชี้ไปที่ jQuery2 และฉันมีวัตถุจาก namespace ด้านนอก (โดยที่ $ คือ jQuery1) กว่าฉันไม่มีวิธีใช้ instanceof สำหรับตรวจสอบว่าวัตถุนี้เป็นวัตถุ jQuery
Georgii Ivankin

6
หากคุณไม่แน่ใจว่ามีการโหลด jQuery ในช่วงเวลาของคำสั่ง if หรือไม่คุณสามารถขยายการตรวจสอบtypeof jQuery === 'function' && obj instanceof jQueryเนื่องจากjQueryไม่ต้องประกาศเพื่อให้typeofผู้ปฏิบัติงานทำงานได้โดยไม่ผิดพลาด
Patrick Roberts

105

คุณอาจใช้คุณสมบัติ. jquery ตามที่อธิบายไว้ที่นี่: 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
เมื่อเดวิดชี้ไปที่คำถามการตรวจสอบคุณสมบัติของตัวแปรที่มีค่าอาจเป็นโมฆะ (เช่นถ้า "a" หรือ "b" เป็นโมฆะ) ไม่ปลอดภัย (มันจะโยน TypeError) การใช้ "b instanceof jQuery" ดีกว่า
rstackhouse

23
วิธีนี้ใช้งานได้หากไม่ได้โหลด jQuery ในขณะที่b instanceof jQueryโยน ReferenceError หาก jQuery ไม่สามารถใช้ได้ในหน้านั้น ทั้งสองวิธีมีประโยชน์ในหลายกรณี
เนท

อาจจะมีประสิทธิภาพมากกว่า แต่ก็ยังไม่ปลอดภัย มันอาจต้องการtry ... catchโดยเฉพาะอย่างยิ่งใน oldie
ClarkeyBoy

ในกรณีที่ไม่สามารถโหลด jQuery ได้คุณสามารถใช้if ((typeof jQuery !== 'undefined') && (obj instanceof jQuery)) {...
Harry Pehkonen

นั่นไม่ใช่ตัวอย่างที่ดี .. มีแนวโน้มว่าaจะเป็นโหนด DOM ในdocument.bodyทางทฤษฎีแล้วมีโอกาสที่jqueryกุญแจจะมาอยู่บนห่วงโซ่ของโหนดนั้น
vsync


26

วิธีที่ดีที่สุดในการตรวจสอบอินสแตนซ์ของวัตถุคือผ่านโอเปอเรเตอร์ของอินสแตนซ์หรือด้วยเมธอดisPrototypeOf ()ซึ่งตรวจสอบว่าต้นแบบของวัตถุอยู่ในห่วงโซ่ต้นแบบของวัตถุอื่นหรือไม่

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

แต่บางครั้งมันอาจล้มเหลวในกรณีของอินสแตนซ์ jQuery หลายรายการในเอกสาร ในฐานะ @Georgiy Ivankin พูดถึง:

ถ้าฉันมี$ใน namespace ปัจจุบันของฉันชี้ไปที่jQuery2และฉันมีวัตถุจาก namespace ด้านนอก (ที่$อยู่jQuery1) แล้วฉันไม่มีวิธีที่จะใช้instanceofสำหรับการตรวจสอบว่าวัตถุนั้นเป็นjQueryวัตถุ

วิธีหนึ่งที่จะเอาชนะปัญหานั้นได้คือการใช้นามแฝงวัตถุ jQuery ในการปิดหรือIIFE

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

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

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

วิธีอื่นในการเอาชนะปัญหานั้นคือการสอบถามjqueryคุณสมบัติในobj

'jquery' in obj

อย่างไรก็ตามหากคุณพยายามทำการตรวจสอบด้วยค่าดั้งเดิมมันจะทำให้เกิดข้อผิดพลาดดังนั้นคุณสามารถแก้ไขการตรวจสอบก่อนหน้าได้โดยทำให้แน่ใจว่าobjเป็นObject

'jquery' in Object(obj)

แม้ว่าวิธีก่อนหน้านี้จะไม่ปลอดภัยที่สุด (คุณสามารถสร้าง'jquery'คุณสมบัติในวัตถุ) แต่เราสามารถปรับปรุงการตรวจสอบโดยการทำงานกับทั้งสองวิธี:

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

ปัญหาที่นี่คือวัตถุใด ๆ ที่สามารถกำหนดคุณสมบัติjqueryเป็นของตัวเองดังนั้นวิธีที่ดีกว่าคือการถามในต้นแบบและให้แน่ใจว่าวัตถุนั้นไม่ได้nullหรือundefined

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

เนื่องจากการบังคับของifคำสั่งที่จะทำให้ไฟฟ้าลัดวงจรโดยการประเมิน&&ผู้ประกอบการเมื่อobjมีการใด ๆ ของfalsyค่า ( null, undefined, false, 0, "") และจากนั้นก็จะดำเนินการตรวจสอบอื่น ๆ

ในที่สุดเราสามารถเขียนฟังก์ชั่นยูทิลิตี้:

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

ลองดูที่: ผู้ประกอบการตรรกะและความจริง / เท็จ


มันช่วยปรับปรุงความปลอดภัยอย่างไร? วัตถุที่ไม่ใช่ jQuery ที่มีคุณสมบัติ jquery จะยังคงถูกตรวจสอบผิด ฉันไม่เห็นว่าสิ่งใดที่ใช้ทั้งสองวิธีนี้อาจ "ปรับปรุง" เช่นกัน
Gui Prá

นี่เป็นวิธีที่ง่ายในการตรวจสอบว่าวัตถุเป็นวัตถุ jQuery หรือไม่ถ้าด้วยเหตุผลใดก็ตามที่คุณสงสัยว่ามีใครบางคนกำลังสร้างวัตถุที่มีคุณสมบัติเช่นjqueryคุณสามารถสร้างตัวตรวจสอบความถูกต้องได้มากขึ้นเช่นการตรวจสอบคุณสมบัติในต้นแบบ: myObj .constructor.prototype.jqueryหรือดีกว่าคุณสามารถใช้ฟังก์ชันObject.prototype.isPrototypeOf ()
jherax

1
หากคุณ||มีสิ่งใดสิ่งหนึ่งที่มี a 'jquery' in Object(obj)จะไหลไปเพราะจะไม่ป้องกันวัตถุที่ไม่ใช่ jQuery ด้วยคุณสมบัตินั้นจากการผ่านการตรวจสอบ ฉันเชื่อว่าการตรวจสอบคุณสมบัตินั้นในต้นแบบช่วยปรับปรุงสถานการณ์ให้ดีขึ้น บางทีคุณควรเพิ่มคำตอบของคุณ! ฉันไม่คิดว่าคำตอบอื่น ๆ ที่นี่กล่าวว่าเป็นไปได้ :)
กุยพระ

1
ไม่ได้เป็นobj.__proto__.jqueryแทนobj.constructor.prototype.jqueryเพียงพอหรือไม่ สั้นไปหน่อย :)
Axel

1
@Axel ใช่มันก็ทำงานได้เหมือนกัน :) ผมใช้constructor.prototypeเพราะควรจะเป็นตัวอย่างของการสร้างที่เป็นobj jQueryในทางกลับกัน__proto__สามารถใช้ได้กับวัตถุทุกชนิด
jherax

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

ในการตรวจสอบองค์ประกอบ DOM ให้ใช้nodeTypeทรัพย์สินได้ดีขึ้นและเพื่อให้แน่ใจว่าได้รับbooleanค่าคืนคุณสามารถใช้การปฏิเสธแบบคู่ได้!!(el && el.nodeType)
jherax

3

อย่างไรก็ตามมีอีกหนึ่งวิธีในการตรวจสอบวัตถุใน jQuery

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

ฉันได้ทำตัวอย่างเพื่อทำความเข้าใจกับสิ่งต่าง ๆลิงก์ jsfiddle


2

สำหรับผู้ที่ต้องการทราบว่าวัตถุเป็นวัตถุ jQuery โดยไม่ต้องติดตั้ง jQuery ข้อมูลโค้ดต่อไปนี้ควรทำงาน:

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

คุณสามารถตรวจสอบว่าวัตถุถูกผลิตโดย JQuery ด้วยjqueryคุณสมบัติ:

myObject.jquery // 3.3.1

=> ส่งคืนหมายเลขรุ่น JQuery ถ้าวัตถุที่สร้างโดย JQuery => มิฉะนั้นจะส่งคืนundefined


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

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

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

11
การทิ้งโค้ดโดยไม่มีคำอธิบายนั้นไม่ค่อยมีประโยชน์ โปรดพิจารณาเพิ่มบริบทในคำตอบของคุณ
Chris
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.