Last Updated: May 04, 2019
·
2.8K
· emi420

How to make a cool $() selector

I know that %98 of times all you need is download jQuery, but you can learn some little things of how frameworks work making your own tiny-framework.

(This is my first write in english, don't blame on me)

Maybe you've learned that you can use functions that works as constructors and make new shiny instance objects. Something like this:

var Dog = function(options) {
    this.name = options.name;
    this.voice =  options.voice;
};

var dogMaker = function(options) {
   return new Dog(options);
};

var myDog = dogMaker({
    name: "Tango",
    voice: "woof!"
});

And maybe you know, that the $ symbol is valid in JavaScript, and can be used as the name of any object:

var myToolbox = function(query) {
     var el = document.querySelectorAll(query),
         i;
     for(i = 0; i < el.length; i++) {
         this[i] = el[i];
     }
     this.length = i;
}

var $ = function(query) {
    return new myToolbox(query);
}

Using this code you can create new objects from querySelectorAll queries, like $("body") $("#myDivId") $(".myClass").

The next step is to add some methods to the prototype of the instance objects, so will be available to all instances:

myToolbox.prototype = {
    show: function() {
        this[0].style.display = "block";
    },
    hide: function() {
        this[0].style.display = "none";
    }
}

And now you can do some interesting things like:

$("body").show();
$("body").hide();

If you write $("div").length, it will work and return the number of div elements on the document. Write only $("div") and you will see that the returned value is not an Array, but a myToolbox object. So if we want to workaround this and return an Array as the response, we can inherits Array's prototype:

$.prototype = myToolbox.prototype = [];

Here is the final code, enjoy it!

var myToolbox = function(query) {
     var el = document.querySelectorAll(query);
     for(i = 0; i < el.length; i++) {
         this[i] = el[i];
     }
     this.length = i;
}

var $ = function(query) {
    return new myToolbox(query);
}

$.prototype = myToolbox.prototype = [];

myToolbox.prototype.show = function() {
    this[0].style.display = "block";
};

myToolbox.prototype.hide = function() {
    this[0].style.display = "none";
};

7 Responses
Add your response

Nice writeup. I sometimes think that prototypal inheritance is so much more powerful than class-based inheritance. (That's assuming it's used the right way.)

over 1 year ago ·

rally informative, thanks mate!

over 1 year ago ·

drop the loop and use:

this.push.apply(this, document.querySelectorAll(query));

and drop the return too ... there is no need to return this; in JavaScript, that is what a constructor returns in any case.

over 1 year ago ·

@webreflection I like to be explicit in this example, because is for educational purposes. But if anyone use this code, these tips are useful.

Thanks!

over 1 year ago ·

Here's a more portable/maintainable approach for a jQuery-like library:
https://gist.github.com/elclanrs/5341331

over 1 year ago ·

emi420 ... returning this in a constructor is not educational, is just wrong understanding/teaching of how a constructor work, sorry

over 1 year ago ·

@webreflection Ok, 'return this' is valid, but the constructor returns 'this' anyway. Removed from the code.

Regards

over 1 year ago ·