ตรวจสอบว่าวัตถุเป็นวัตถุ 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.