7

So I've come across to an answer but it is not enough to expand my knowledge base.

I've been searching for ages what the x = x || y, z means in StackOverflow

I found this. What does the construct x = x || y mean?

But the problem is what is the , z for?

I'm seeing these expressions quite often window.something = window.something || {}, jQuery

I already know that if false was returned on the first argument then {} will be assigned to the something property.

My question is, What is the , jQuery for?

Can someone enlighten me and shower me with this very important knowledge?

UPDATE 8/11/2014

So I tried making tests.

var w = 0, x = 1,y = 2,z = 3;
var foo = w || x || y, z; //I see that z is a declared variable
console.log(foo); //outputs 1

and it is the same as this.

var w = 0, x = 1,y = 2;
var z = function(){return console.log("this is z");}
var foo = w || x || y, z; //same as this
console.log(foo); //still outputs 1

another.

var w = 0, x = 1,y = 2;
var z = function(){return console.log("this is z");}
function foobar(){
this.bar = console.log(foo,z);
}(foo = w || x || y, z);
foobar(); //outputs 1 and string code of foobar

changing the value of z in (foo = w || x || y, z).

var w = 0, x = 1,y = 2;
var z = function(){return console.log("this is z");}
function foobar(){
this.bar = console.log(foo,z);
}(foo = w || x || y, z=4);
foobar(); //outputs 1 and 4

I assume that placing variables inside ( ) after the } of the function is the same as declaring a new variable.

Another test.

var w = 0, x = 1,y = 2,z = 1;
function foobar(){
    var bar = 10,z=2;
        console.log(z);
}(foo = w || x || y, z=4);
console.log(foo,z); // Seems that foo is public and made an output
foobar(); // outputs the z = 2 inside and disregards the z = 4 from (..., z=4)
console.log(z); // It seems that z is 4 again after calling foobar

However, in a scenario like this. Link to JSFiddle

//Self-Executing Anonymous Function: Part 2 (Public & Private)
(function( skillet, $, undefined ) {
    //Private Property
    var isHot = true;

    //Public Property
    skillet.ingredient = "Bacon Strips";

    //Public Method
    skillet.fry = function() {
        var oliveOil;

        addItem( "\t\n Butter \n\t" );
        addItem( oliveOil );
        console.log( "Frying " + skillet.ingredient );
    };

    //Private Method
    function addItem( item ) {
        if ( item !== undefined ) {
            console.log( "Adding " + $.trim(item) );
        }
    }    
}( window.skillet = window.skillet || {}, jQuery ));

//Public Properties
console.log( skillet.ingredient ); //Bacon Strips

//Public Methods
skillet.fry(); //Adding Butter & Fraying Bacon Strips

//Adding a Public Property
skillet.quantity = "12";
console.log( skillet.quantity ); //12

//Adding New Functionality to the Skillet
(function( skillet, $, undefined ) {
    //Private Property
    var amountOfGrease = "1 Cup";

    //Public Method
    skillet.toString = function() {
        console.log( skillet.quantity + " " + 
                     skillet.ingredient + " & " + 
                     amountOfGrease + " of Grease" );
        console.log( isHot ? "Hot" : "Cold" );
    };    
}( window.skillet = window.skillet || {}, jQuery ));

try {
    //12 Bacon Strips & 1 Cup of Grease
    skillet.toString(); //Throws Exception
} catch( e ) {
    console.log( e.message ); //isHot is not defined
}

It seems that if you remove the , jQuery it only logs "Bacon Strips" Refer to this link Link to another JSFiddle (, jQuery is removed)

I don't really get this.. But why is the , jQuery inside the ( ) after the } of a function counts as a reference for the code to run completely when the library of jQuery is already included?

Having the $.trim removed from the code, it seems to work fine again. But I still don't get how this referencing works. Link to the JSFiddle without the , jQuery and $.trim

Community
  • 1
  • 1
Mike Ante
  • 746
  • 1
  • 6
  • 18
  • 9
    can you share a context in which you have seen this... it is normally done in local variable declarations like `var p = x || y, z` to declare 2 local variables... but as user2864740 said those are just 2 different statements – Arun P Johny Aug 11 '14 at 03:27
  • 4
    Maybe it was `var x = x || y, z`... – johnwait Aug 11 '14 at 03:29
  • 4
    Is this in a function call? This looks very much like it’s passing `jQuery`. You should add context. – Ry- Aug 11 '14 at 03:30
  • @johnwait Good call, showing just how much a broader context would clear things up .. – user2864740 Aug 11 '14 at 03:31
  • 1
    Expanding slightly on what @ArunPJohny has said, `var p = x || y, z` could be equated to `var p = x || y` **and** `var z` (two separate definitions). `z` would still be "undefined" by value. It would be similar to something like `var foo = 'bar', bar = 'foo', you = 'see?';` – scrowler Aug 11 '14 at 03:37
  • Hi guys, I am close to getting to the answer and I've updated my post, I still don't get how it really works. I've added context to have a clearer view of this problem. – Mike Ante Aug 11 '14 at 06:48

1 Answers1

6

The Comma Operator in JavaScript evaluates operands and returns the value of the last one (right-most). By JS Operator Precedence, the OR operation will be evaluated first, followed by the assignment.

So this expression x = x || y, z is in effect (x = (x || y)), z. The OR operator will either return the boolean result of the comparison or, for non-boolean types, the first operand if it is truthy, or the second operand otherwise. The assignment operator is also higher precedence than the comma operator, so x will be assigned the value returned by the OR. The value of z will not have any effect on either the OR operation or the assignment. In fact, it will be evaluated last, meaning it is essentially a separate statement with no effect on anything else in that 'expression.' I can't see any practical value in writing the expression that way.

nbrooks
  • 18,126
  • 5
  • 54
  • 66
  • I see.. But I still don't understand why is z there in the first place. Here is a jQuery example. http://jsfiddle.net/fssj71mp/1/ I'm trying to understand what the `,jQuery` is for. Thank you for the effort. This might be close to the answer I'm looking for but not exactly what I had in mind. +1 I updated my post, please see if there is any explanation for this. Thank you :) – Mike Ante Aug 11 '14 at 06:43
  • 1
    @Mike In that case the comma is simply separating function arguments. Take a look at this [jsFiddle](http://jsfiddle.net/fssj71mp/8/). It's the typical process: define a func. that takes two args `function foo(a, b) {...}`. Then you call it by doing `foo(1, 2)`. Your example is basically `foo(a, b)`, but you're simply defining your function as anonymous and self-executing. Your first param (`a`) is also a more complex expression: `window.skillet = window.skillet || {}` (simply ensuring that the variable `skillet` is defined globally). So `, jQuery` is just passing in the second param `b`. – nbrooks Aug 11 '14 at 20:23
  • I see... One last Question.. Before I mark this as the answer. `(function somefunction(a,b) {console.log(a,b);}(1,2));` In this little code, `(a,b)` means the parameters and adding `(1,2)` after the `}` means that you are calling the function itself am I right? and if you call the `somefunction(a,b)` with new arguments `somefunction(3,4)` the values `(1,2)` will still be reused unless they were overwritten am I right? – Mike Ante Aug 12 '14 at 03:41
  • @Mike In that case you wouldn't be able to re-use the function at all, since the entire statement was not a function declaration but a method call. You won't be able to reference `somefunction` in the global scope (though it can reference itself recursively). Give it a try, you'll get a `somefunction is not defined` error, or something similar. If you just define a named function in one statement and call it with `(1,2)` in a different statement, a separate call with `(3,4)` would not know anything about the original params (barring some caching/global variable techniques). – nbrooks Aug 12 '14 at 23:17
  • I tried something and that helped a lot! Thanks Mr. brooks! http://jsfiddle.net/n01ojnba/1/ – Mike Ante Aug 13 '14 at 01:29