0

I've been going through the jQuery code and I have seen a few links that have this question. I am asking it again because I did not really understand any of them so please do not mark this question as duplicate. I've gone through the following stackoverflow links:

How can jQuery return an array and still have it to be a jQuery object

How does jQuery chaining work

How does jQuery return an array of the selected objects

Gone through all of those links and I do not get how it works. All I ask is a very simple example of returning an array from a constructor object and still chaining it. I have tried the following code:

(function(window, document, undefined)
{
    var lhd = function(selector)
    {
        return new Lhd(selector);
    }

    function Lhd(selector)
    {
        var elem = document.querySelectorAll(selector),
            elems = {};

        return this.makeArray(elems, elem);
    }

    Lhd.prototype = {
        makeArray: function(arr, result)
        {
            var ret = result || [];

            Array.prototype.push.apply(ret, arr);

            return ret;
        },

        click: function()
        {
            console.log('click');

            return this;
        }
    };

    window.lhd = lhd;
})(window, document);

I'm able to return an array but unable to chain it.

Community
  • 1
  • 1
Hawk
  • 167
  • 2
  • 12
  • 2
    you shouldn't return from a constructor. – Daniel A. White Jul 23 '15 at 01:45
  • `makeArray` returns not `this` but something else. How are you going to chain it? – zerkms Jul 23 '15 at 01:47
  • the makeArray is returning the same as the jQuery code returns @zerkms – Hawk Jul 23 '15 at 01:51
  • @DanielA.White, please elaborate more. How should I go about to chain it? – Hawk Jul 23 '15 at 01:51
  • @Hawk if it is returning the same as jquery then it should work the same as jquery. If it works - why do you ask the question? – zerkms Jul 23 '15 at 01:55
  • `How should I go about to chain it?` --- chaining is not a magic (and I'm not even sure why people have thought of a special "chaining" term for that), but just returning *some* instance that has the next called method defined. – zerkms Jul 23 '15 at 01:56
  • From the answer to the first question you've linked: "*jQuery objects are **array-like**, so look and behave a lot like arrays, but are in fact just **custom objects***". Did you understand what this means? There are no arrays. – Bergi Jul 23 '15 at 02:00
  • `jQuery.makeArray` is **not** chainable, it returns JavaScript `Array`, which is different to `jQuery object`. – Neverever Jul 23 '15 at 02:16
  • @Bergi, yes, I know what they mean by array-like objects – Hawk Jul 23 '15 at 02:21
  • At this point, a small piece of code would be helpful – Hawk Jul 23 '15 at 02:21

1 Answers1

1

I'm able to return an array

You must not return an array, you must make the new instance (this) become array-like.

function lhd(selector) {
    return new Lhd(selector);
}

function Lhd(selector) {
    var elems = document.querySelectorAll(selector);

    this.length = 0; // initialise a length
    Array.prototype.push.apply(this, elems); // push onto the instance

    // don't `return` anything - it's a constructor
}

Lhd.prototype.click = function() {
    console.log('click');
    return this;
};

You can use it now like lhd('a').click().click().

Bergi
  • 630,263
  • 148
  • 957
  • 1,375