2

I'm working on samsung SDK and modifying a javascript app for smart tv. I stumbled upon this piece of code and I don't understand what if($('.menuButton').push()){... does. The native push function was not overwrited but this still works. I thought push will append an element to an array, but this doesn't seem to be the case

if(direction==tvKey.KEY_ENTER){
        if($('.menuButton').push()){
            $('.simple_menu').slideDown('easy');
     ........
kapa
  • 77,694
  • 21
  • 158
  • 175
Mircea Voivod
  • 721
  • 1
  • 10
  • 20
  • 1
    That looks like a bug to me. There is no documented `.push()` API. – Pointy Jan 25 '13 at 14:41
  • [Although jQuery objects act like arrays, they are actually only array-like objects.](http://stackoverflow.com/questions/1483445/how-do-jquery-objects-imitate-arrays) – jbabey Jan 25 '13 at 14:52

3 Answers3

3

Calling .push(x) on a JQuery selector acts the same as calling .push(x) on a normal array in Javascript.

From W3Schools and the Mozilla Developer Network:

The push() method adds new items to the end of an array, and returns the new length.

and

Returns: The new length property of the object upon which the method was called.

If no arguments are passed to .push(), then the array is left as-is, and the length is still returned. So what is happening here is the array length is being returned and used to evaluate the if statement.

Example: The following will return the number of p tags:

$("p").push();

But Beware: The .push method for JQuery objects is marked for internal use only and thus should not be depended on.

WilHall
  • 11,644
  • 6
  • 31
  • 53
  • 2
    Except that a jQuery object and an array are two completely distinct and separate objects that do not share the same methods. Also, http://www.w3fools.com – jbabey Jan 25 '13 at 14:45
  • @jbabey You're right, they are different objects. However, JQuery objects can be accessed like arrays. Try it. And see my example above of `$("p").push()`. – WilHall Jan 25 '13 at 14:48
  • The fact that `push` happens to work on a jQuery object is an undocumented "feature" (read: bug) and thus should never be coded against. What happens when the jQuery team decides to implement a real `jQuery.prototype.push` and all of your code using push breaks? – jbabey Jan 25 '13 at 14:50
  • Yea, this is right. Thanks, and also was a bug in the script. – Mircea Voivod Jan 25 '13 at 14:53
  • 1
    @jbabey Understand that I completely agree. I was just attempting to shine light on *why* this worked. I don't make use of this "feature", and I wouldn't recommend anyone do so. – WilHall Jan 25 '13 at 14:54
  • 1
    It is no bug, and it is documented in the source code. The jQuery object **has** and intentional `push()` method (marked for internal use though, so you should not use it), and it maps to `Array.prototype.push`. This means that in the end it is the same method as the native one... – kapa Jan 25 '13 at 14:56
  • [The part of the source code where `push` is defined](https://github.com/jquery/jquery/blob/master/src/core.js#L263). – kapa Jan 25 '13 at 15:08
1

This method should not be relied upon. Don't use it.

push() is defined on the jQuery object (which is an array-like object), and it maps to the native Array.prototype.push() method, but it is meant for internal use only, not documented and you cannot be sure it will work the same way in future versions.

In this code, it seems to be used to get the number of elements in the jQuery object (which is what the native .push() does, it returns the value of the length property).

But there is a documented way to do that:

$('.menuButton').length

The code relies on the fact that if the length is zero, it will evaluate to false in Javascript when converted to a Boolean, so the code in the if block will only run if the jQuery object is not empty.

kapa
  • 77,694
  • 21
  • 158
  • 175
0

I'm not sure what $().push does or if it even exists (not to be confused with the native JavaScript array.push() method), but you are probably looking for $().add:

Given a jQuery object that represents a set of DOM elements, the .add() method constructs a new jQuery object from the union of those elements and the ones passed into the method.

Also note that a jQuery object can never be false, your if statement should probably be:

if($('.menuButton').add(something).length > 0) {

Edit: it looks like you are using an internal-only, undocumented, and unsupported method of jQuery. If you want to get the length of the current jQuery object (which is what $().push() appears to do), just use length:

if($('.menuButton').length > 0) {
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • 1
    In fact, the value returned by `$()` is an array, and thus has the native `.push()` method, like any array. – kapa Jan 25 '13 at 14:47
  • @bažmegakapa the value returned by the jQuery function is a jQuery object, not an array. – jbabey Jan 25 '13 at 14:47
  • 1
    @jbabery OK, I'm not totally right with this. The jQuery object is an array-like object, it lets you use `[]` operator on it, has `length` property and implements some array functions (and `push()` is one of them). You can check the source code for that (`push: core_push,`), it has a note: `// For internal use only.`. – kapa Jan 25 '13 at 14:53
  • @bažmegakapa which means the jQuery team has the right to change/delete it whenever they please, and anyone who consumed it is out of luck. – jbabey Jan 25 '13 at 14:56
  • I totally agree with that point, it should not be relied upon (you can use `.length` or `.size()` instead). – kapa Jan 25 '13 at 15:00