How can a jQuery object behave like an array, although it's not one?

I always thought that the jQuery function $returns an array with jQuery methods attached to it. I want to give some examples:

Say we have an array

var arr = [1,2,3];

Then we can add our own properties:

arr.someProp = 10;
arr.someMethod = function() { ... }

After that, it arrremains an array, despite user properties:

arr instanceof Array;   //true

So, I thought the jQuery object was something like arr(but more complex) until a recent experiment. I just run this code:

$('div') instanceof Array;  //false (!!!)

But it behaves like an array. It has a property push, a property lengththat works correctly even in this case:

var $jq = $('div');
$jq.length; //3
$jq.push(123);  //wrong code, I know, this is just for test
$jq.length      //4

Also, if you execute console.log($('div')), it will output something like this:

[<div></div>, <div></div>, <div></div>]

, jQuery , Array.prototype :

$('div').sort === Array.prototype.sort;     //true
$('div').splice === Array.prototype.splice; //true

: ?

, , , , .

+4
4

, , jQuery - arr ( ) . :

$('div') instanceof Array;  //false (!!!)

. push, length, ...

" " , Array, .length .

:

var obj = {
    "3": "buz",
    "0": "foo",
    "2": "baz",
    "1": "bar",
    length: 4
}

, Array.prototype.push , .

obj.push = Array.prototype.push;

obj.push("hi");

obj .length of 5 "hi".

+4

jQuery - , . , , .

Javascript , , , document.getElementsByTagName, HTMLCollection NodeList ( ), , .

, , , , , .

:

var myArrayLookAlike = {
  length: 0,
  data: [],
  push: function(value){
    this.data.push(value);
    this.length = this.data.length;
  },
  pop: function(){
    var value = this.data.pop(value);
    this.length = this.data.length;
    return value;
  }
};

jQuery makeArray, , , , , , , .

+3

: ?

, , -jQuery . jQuery , , return this , . map - " ", , , map . toArray, flatten unique, . jQuery , , , , jQuery, JavaScript (checkout Zepto.js):

var $ = (function(){ // jQuery shortcut

  // Helpers to work with collections of elements

  // Converts pseudo-arrays to real arrays
  // such as elements queried with native DOM methods
  var toArray = function(x) {
    return Array.prototype.slice.call(x);
  };
  // Flattens array of arrays, one level
  var flatten = function(xs) {
    return Array.prototype.concat.apply([], xs);
  };
  // Remove duplicates
  var unique = function(xs) {
    return xs.filter(function(x, i) {
      return xs.indexOf(x) == i;
    });
  };
  // Query the DOM on the document or an element
  var query = function(sel, el) {
    return toArray((el || document).querySelectorAll(sel));
  };
  // Helper to access object properties with `map`
  var dot = function(s) {
    return function(x) {
      return x[s];
    };
  };

  // Constructor
  function jQuery(sel) {
    // Elements queried from the DOM
    // as an array
    this.el = query(sel);
    this.length = this.el.length;
  }

  // Public methods that operate on the array
  // of queried elements
  jQuery.prototype = {
    // Return array (collection of elements)
    get: function(idx) {
      return idx == null ? this.el : this.el[idx];
    },
    // Map is the core method,
    // all other methods use `map` in way or the other
    map: function(fn) {
      var f = function(x) {
        var fx = fn.call(this, x);
        // It a pseudo-array?
        if (fx.length) return toArray(fx);
        return fx;
      };
      this.el = unique(flatten(this.el.map(f)));
      this.length = this.el.length;
      return this; // chain

    },
    parent: function() {
      return this.map(dot('parentNode'));
    },
    children: function() {
      return this.map(dot('children'));
    }
  };

  // Wrapper around construtor
  // to create new instances without `new`
  return function(sel) {
    return new jQuery(sel);
  };
}());
+1

This is an example that I used to submit a form that can help you with your question.

JS code

 // process the form
        $('.updateClient').click(function(event) {

            // get the form data
            // there are many ways to get this data using jQuery (you can use the class or id also)
            var formData = {    
                'clientbrandid' :$("input[id=editClientBrand]").val()
            };

            // process the form
            var ajaxResponse = $.ajax({
                type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
                url: 'someURL', // the url where we want to POST
                data: JSON.stringify( formData ),
                contentType :'application/json',
                error: function(data,status,error){
                            console.log(data+': '+status+': '+error);
                                            }
                    }).done(function(apiResponse) {
                            $('.someClass').append('Hello There!'); //This is what creates the <div></div> on the html side and when the function is done it appends the content between those two <div></div>
                    });

    });

HTML side

..............Some form code on top of this.

    <div class='someClass'></div> <--- this is where the output will show after the code is done
0
source

All Articles