Kiểm tra xem đối tượng có phải là đối tượng jQuery không


602

Có cách nào nhanh chóng để kiểm tra xem một đối tượng là đối tượng jQuery hay đối tượng JavaScript nguyên gốc không?

thí dụ:

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

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

doStuff(o);
doStuff(e);

rõ ràng, đoạn mã trên hoạt động nhưng nó không an toàn. Bạn có khả năng có thể thêm khóa chọn vào ođối tượng và nhận được kết quả tương tự. Có cách nào tốt hơn để đảm bảo rằng đối tượng thực sự là một đối tượng jQuery không?

Một cái gì đó phù hợp với (typeof obj == 'jquery')


3
Đối với jQuery 3.0, đây chắc chắn không phải là một cách chính xác để kiểm tra một đối tượng là đối tượng jQuery vì thuộc selectortính đã bị từ chối từ lâu và bị xóa trong 3.0. Ngay cả trong các phiên bản trước, một đối tượng jQuery có thể có một chuỗi bộ chọn trống, ví dụ $(window)không có bộ chọn. Sử dụng instanceofthay thế.
Dave Methvin

Câu trả lời:


878

Bạn có thể sử dụng instanceoftoán tử:

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

Giải thích : jQueryhàm (aka $) được thực hiện như một hàm xây dựng . Các hàm xây dựng sẽ được gọi với newtiền tố.

Khi bạn gọi $(foo), jQuery bên trong sẽ dịch cái này thành new jQuery(foo)1 . JavaScript tiến hành khởi tạo thisbên trong hàm xây dựng để trỏ đến một phiên bản mới của jQuery, đặt các thuộc tính của nó thành các thuộc tính được tìm thấy trên jQuery.prototype(aka jQuery.fn). Vì vậy, bạn có được một newđối tượng mà instanceof jQuerytrue.


1 Thật ra new jQuery.prototype.init(foo): logic của hàm tạo đã được giảm tải cho hàm xây dựng khác được gọi init, nhưng khái niệm này là như nhau.


8
Vậy ý bạn là if (obj instanceof jQuery){...}gì?
Thiên thần Nigel

2
@NigelAngel: Yup, đó là ý anh ấy :)
ChaseMoskal

12
Điều này không hoạt động trong trường hợp có nhiều phiên bản jQuery trên một trang.
Georgii Ivankin

5
@CrescentFresh Ý tôi là nếu tôi có $ trong không gian tên hiện tại của tôi trỏ đến jQuery2 và tôi có một đối tượng từ không gian tên bên ngoài (trong đó $ là jQuery1) thì tôi không có cách nào để sử dụng instanceof để kiểm tra xem đối tượng này có phải là đối tượng jQuery không.
Georgii Ivankin

6
Nếu bạn không chắc chắn liệu jQuery được nạp tại thời điểm câu lệnh if, bạn có thể mở rộng việc kiểm tra là typeof jQuery === 'function' && obj instanceof jQuerytừ jQuerykhông nhất thiết phải được khai báo để các typeofnhà điều hành để làm việc mà không ném một lỗi.
Patrick Roberts

105

Bạn cũng có thể sử dụng thuộc tính .jquery như được mô tả ở đây: 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
Như David đã chỉ ra trong câu hỏi, việc kiểm tra thuộc tính của một biến có giá trị có thể là null (nghĩa là nếu "a" hoặc "b" là null) không an toàn (nó sẽ ném TypeError). Sử dụng "b instanceof jQuery" là tốt hơn.
kho

23
Cách này hoạt động nếu jQuery không được tải, trong khi b instanceof jQueryném ReferenceError nếu jQuery không có sẵn trên trang. Cả hai phương pháp đều hữu ích trong các trường hợp khác nhau.
Nate

Hiệu quả hơn có thể, nhưng vẫn không an toàn. Nó có thể yêu cầu try ... catch, đặc biệt là trong oldIE.
ClarkeyBoy

Trong trường hợp có thể jQuery không được tải, bạn có thể sử dụngif ((typeof jQuery !== 'undefined') && (obj instanceof jQuery)) {...
Harry Pehkonen

Đó không phải là một ví dụ tốt .. nhiều khả năng asẽ là một nút DOM, như document.bodyvà sau đó, về mặt lý thuyết, có khả năng jquerykhóa bằng cách nào đó đã xuất hiện trong chuỗi của nút đó.
vsync


26

Cách tốt nhất để kiểm tra thể hiện của một đối tượng là thông qua toán tử instanceof hoặc với phương thức isPrototypeOf () để kiểm tra xem nguyên mẫu của một đối tượng có nằm trong chuỗi nguyên mẫu của đối tượng khác hay không.

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

Nhưng đôi khi nó có thể thất bại trong trường hợp có nhiều phiên bản jQuery trên một tài liệu. Như @Georgiy Ivankin đã đề cập:

nếu tôi có $trong không gian tên hiện tại của tôi trỏ đến jQuery2và tôi có một đối tượng từ không gian tên bên ngoài ( $thì là jQuery1) thì tôi không có cách nào để sử dụng instanceofđể kiểm tra xem đối tượng đó có phải là một jQueryđối tượng không

Một cách để khắc phục vấn đề đó là bằng cách đặt bí danh cho đối tượng jQuery trong bao đóng hoặc IIFE

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

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

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

Một cách khác để khắc phục vấn đề đó là tìm hiểu jquerytài sảnobj

'jquery' in obj

Tuy nhiên, nếu bạn cố gắng thực hiện kiểm tra đó với các giá trị nguyên thủy, nó sẽ gây ra lỗi, vì vậy bạn có thể sửa đổi kiểm tra trước đó bằng cách đảm bảo objlà mộtObject

'jquery' in Object(obj)

Mặc dù cách trước đó không an toàn nhất (bạn có thể tạo thuộc 'jquery'tính trong một đối tượng), chúng tôi có thể cải thiện xác thực bằng cách làm việc với cả hai phương pháp:

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

Vấn đề ở đây là bất kỳ đối tượng nào cũng có thể định nghĩa một thuộc tính jquerylà của riêng mình, vì vậy cách tiếp cận tốt hơn sẽ là hỏi trong nguyên mẫu và đảm bảo rằng đối tượng đó không nullhoặcundefined

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

Do sự ép buộc , các iftuyên bố sẽ làm ngắn mạch bằng cách đánh giá các &&nhà điều hành khi objlà bất kỳ falsy giá trị ( null, undefined, false, 0, ""), và sau đó tiến hành để thực hiện việc kiểm chứng thực khác.

Cuối cùng chúng ta có thể viết một hàm tiện ích:

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

Chúng ta hãy xem: Toán tử logic và trung thực / giả


Làm thế nào để cải thiện sự an toàn, mặc dù? Các đối tượng không phải là jQuery có thuộc tính jquery vẫn sẽ bị đánh giá sai. Tôi cũng không thấy những gì khác sử dụng cả hai phương pháp có thể "cải thiện".
Gui Prá

Đây là một cách dễ dàng để kiểm tra xem một đối tượng có phải là đối tượng jQuery hay không, nếu vì bất kỳ lý do nào bạn nghi ngờ rằng ai đó đang tạo các đối tượng có các thuộc tính như jquery , thì bạn có thể tạo một trình xác nhận mạnh mẽ hơn, tức là kiểm tra các thuộc tính trong nguyên mẫu: myObj .constructor.prototype.jquery hoặc tốt hơn nữa, bạn có thể sử dụng hàm Object.prototype.isPrototypeOf ()
jherax

1
Tuy nhiên, nếu bạn thực hiện ||bất kỳ điều gì với 'jquery' in Object(obj)điều đó, vì nó sẽ không ngăn các đối tượng không phải jQuery có thuộc tính đó vượt qua xác minh. Tôi tin rằng việc kiểm tra tài sản đó trong nguyên mẫu sẽ cải thiện tình hình. Có lẽ bạn nên thêm nó vào câu trả lời của bạn! Tôi không nghĩ rằng bất kỳ câu trả lời khác ở đây đề cập đến khả năng đó :)
Gui Pra

1
obj.__proto__.jquerythay vì không obj.constructor.prototype.jqueryđủ? chỉ một chút ngắn thôi :)
Axel

1
@Axel vâng, nó hoạt động quá :). Tôi đã sử dụng constructor.prototypebởi vì objnó được coi là một thể hiện của hàm tạo jQuery. Mặt khác __proto__có sẵn cho bất kỳ loại đối tượng.
jherax

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

Để kiểm tra phần tử DOM, sử dụng thuộc nodeTypetính tốt hơn và để đảm bảo booleangiá trị được trả về, bạn có thể sử dụng phủ định kép!!(el && el.nodeType)
jherax

3

Tuy nhiên, có một cách nữa để kiểm tra đối tượng trong jQuery.

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

Tôi đã làm ví dụ để hiểu mọi thứ, liên kết jsfiddle


2

Đối với những người muốn biết liệu một đối tượng có phải là đối tượng jQuery mà không cài đặt jQuery hay không, đoạn mã sau sẽ thực hiện công việc:

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

Bạn có thể kiểm tra xem đối tượng có được JQuery tạo ra với thuộc jquerytính không:

myObject.jquery // 3.3.1

=> trả về số lượng phiên bản JQuery nếu đối tượng do JQuery tạo ra. => nếu không, nó sẽ trả vềundefined


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

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

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

11
Mã bãi mà không có lời giải thích hiếm khi hữu ích. Vui lòng xem xét thêm một số bối cảnh cho câu trả lời của bạn.
Chris
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.