Can jQuery () objects contain non-DOM objects?

Analyzing the code shown by this SO question , I just noticed a way to use jQuery to iterate through a JSON array:

$(data).each(function() { 

while, in my opinion, the array should be repeated as follows:

 $.each(data, function() { 

In fact, the jQuery.each () man page says:

The $ .each () function does not match $ (selector) .each (), which is used solely to iterate over a jQuery object.

But since the OP seemed to have its code, at least partially working, I was curious to test, and he found that it works!
Here is the proof:

 var data = [ {"key": "value-1"}, {"key": "value-2"}, {"key": "value-3"} ]; $(data).each(function() { document.write('<br />' + this.key); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

So, if $(data).each() works when data is a JSON array, this means that this array is acceptable content for $(data) to return a jQuery object.

Then, after doing research, I checked the jQuery (elementArray) man page and looked at the jQuery( elementArray ) section that says:

elementArray
Type: Array
An array containing a set of DOM elements to wrap a jQuery object.

As stated above, an array of objects (instead of DOM elements) should fail.
Therefore, I tested the comparison of objects returned by either this $(data) or a simple $('body') . Here is the result:

 var data = [ {"key": "value-1"}, {"key": "value-2"}, {"key": "value-3"} ]; function log(obj, init) { for (var prop in obj) { if (obj.hasOwnProperty(prop)) { var $row = $('tr[data-prop=' + prop + ']'); if (!$row.length) { $row = $('<tr data-prop="' + prop + '"><th>' + prop + '</th></tr>') .appendTo($('table')); if (!init) { $row.append('<td></td>'); } } $row.append('<td>' + JSON.stringify(obj[prop]).substr(0,25) + '</td>'); } } } log($('body'), true); log($(data), false); 
 table { border-collapse: collapse; border: 1px solid #000; } th, td { border: 1px solid #000; padding: 5px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <table> <tr> <th>Property</th> <th>$('body')</th> <th>$(data)</th> </tr> </table> 

It actually seems that everything can be converted to a jQuery object.
I'm puzzled: I'm reinventing the wheel !?

+6
source share
2 answers

You read too much in the documentation.

Yes, usually jQuery(elementArray) will be used in an array of elements. But it can be an array of anything.

The goal is to use $.each() and possibly other convenient methods for arrays with regular elements. You will find that other jQuery methods will not match anything in your array if your array does not have any elements.

+1
source

Yes, the jQuery constructor takes an array, and you can iterate through the returned jQuery collection using the $.fn.each method and this in the handler applies to each element. The jQuery collection is an array-like object.

But, no, this does not mean that you can successfully call all the DOM-related methods in the collection. Just try $(data).html() as an example, and you will get an error message because it expects to see a DOM node, not a simple object or string in a collection.

As another example, try $(['foo']).text() and it will throw an Uncaught RangeError: Maximum call stack size exceeded error in jQuery 2.2.2.

And now try:

 /** * `text` reads textContent of DOM elements (nodeType = 1) * and `nodeValue` of textNodes (nodeType = 3) * and returns the concatenated text */ $([ { "nodeType": 1, "textContent": "value-1" }, { "nodeType": 3, "nodeValue": "value-2" }, { "textContent": "I'm a rebel" } ]).text() 

and it returns "value-1value-2" !

+1
source

All Articles