0

Question - brief

Can you call a jQuery method in a chain, from a variable, or can you only use these methods on jQuery objects / elements?

Explanation

we have a custom function

$.fn.example = function(){
    $.each(this, (index, item) => {
        console.log(item);
    }
    return this;
}

This will loop through an object and console.log() each item within.

Let's say there are 3 <p> tags within the HTML.

<p>One</p>
<p>Two</p>
<p>Three</p>

If we call $('p').example() the elements <p>One</p>, <p>Two</p>, <p>Three</p> will be logged to the Console, one after the other.

Question - continued

Does this type of method chaining only work with jQuery Objects, like the above, or is there a way to call this method on a variable?

e.g.

let someArray = ["one", "two", "three"];

someArray.example();

The above code will not work, as example() is not a method of someArray

Question - final

Is there a correct way to call a jQuery method, in a chain, from a variable or object, or can you only call these methods on objects that have been "selected" with jQuery.

If you must first "select" the object with jQuery, is there a way to select a variable, rather than an element of the DOM.

Panomosh
  • 884
  • 2
  • 8
  • 18

4 Answers4

3

Whether it's a variable or not isn't the issue. The issue is what you're interacting with.

You've added example to jQuery.fn, which means it's available on jQuery objects, and not on other kinds of objects, but that's because of what you've specifically done: Added it to the object that jQuery objects use as their prototype.

You can do that with arrays, too:

Object.defineProperty(Array.prototype, "example", {
    value: function() {
        // Your code here
    },
    writable: true,
    configurable: true
});

Live Example:

Object.defineProperty(Array.prototype, "example", {
    value: function() {
        this.forEach(entry => {
            console.log(entry);
        });
        return this;
    },
    writable: true,
    configurable: true
});

var array = ["one", "two", "three"];
array.example();

But, modifying built-in prototypes comes with some major caveats:

  • Always define the new properties you're adding as non-enumerable (the above does that by using Object.defineProperty, which by default adds non-enumerable properties).
  • Always pick names that are unlikely to be used by future JavaScript enhancements. example is unlikely to be used in for future JavaScript enhancements, but generally best to use some kind of completely-unique prefix.
  • If you're writing a library meant to be used by other people, it's best not to modify built-in prototypes at all
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

If I'm not wrong what you want to achieve can be done with $(someArray).example();.

Just try as following.

$.fn.example = function(){
    $.each(this, (index, item) => {
        console.log(item);
    });
    return this;
}

let someArray = ["one", "two", "three"];

$(someArray).example();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
Karan
  • 12,059
  • 3
  • 24
  • 40
1

you need to wrap the array in $() since $.fn['methodName'] only chains to jQuery objects

$.fn.example = function(){
    $.each(this, (index, item) => {
        console.log(item);
    })
    return this;
}

let someArray = ["one", "two", "three"];

$(someArray).example();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
charlietfl
  • 170,828
  • 13
  • 121
  • 150
1

I like the suggestion of @Karan. This is the best way. But if you want to add a method to prototype of the Array, you can do this. But please be careful. Read first why you should not do this: Why is extending native objects a bad practice?

Here is a code you want:

Array.prototype.example = function () {
    this.forEach(function (item) {
        console.log(item);
    });
}

let someArray = ["one", "two", "three"];

someArray.example();

But this is not an good idea!

Damian Dziaduch
  • 2,107
  • 1
  • 15
  • 16