user1492051
user1492051

Reputation: 906

optional arguments and default value

I am new to javascript does the following 2 functions does the same thing and would you pick one over another?

var multiply = function(arg1, arg2) {
             arg1 && (arg1 = 0);
             arg2 && (arg2 = 0);
             return arg1*arg2;
          }


var multiply = function(arg1, arg2) {
             arg1 = arg1 || 0;
             arg2 = arg2 || 0;
             return arg1*arg2;
          }

the reason i am asking is i saw something like this for the first time

  function(path, limit) {
     var ref = firebaseRef(path);
     limit && (ref = ref.limit(limit)); //if i understood correctly this line does an assignment based on condition without an if statement
     return $firebase(ref);
  }

Upvotes: 1

Views: 55

Answers (3)

Scimonster
Scimonster

Reputation: 33399

I think the first one will actually do the opposite of what you want. Let's test this with a few cases:

arg1 && (arg1 = 0);

If arg1 is 0, or any other falsy value, so the execution goes as follows:
0 (meaning false) AND an assignment. The expression will immediately return false without executing the arg1 = 0 statement, because false || (t/f) always returns false.

If arg1 is 1, or any other truthy value, so we have:

1 (meaning true) AND an assignment. The assignment will run this time, because it has to see what the second condition returns. Therefore, arg1 will be set to 0.

The correct snippet is the second.

Upvotes: 1

Sean Quinn
Sean Quinn

Reputation: 2161

Both are variable assignments which evaluate differently on the logical operation.

For example expr1 && expr2 will return expr1 if expr1 returns false otherwise the variable assignment will evaluate to the second expression (i.e. expr2).

Using the logical-or operation will return expr1 if it evaluates to true, otherwise it will return expr2.

Consider the following:

// Logical AND
var a1 =  true && true;     // t && t returns true
var a2 =  true && false;    // t && f returns false
var a3 = false && true;     // f && t returns false
var a4 = false && (3 == 4); // f && f returns false
var a5 = "Cat" && "Dog";    // t && t returns Dog
var a6 = false && "Cat";    // f && t returns false
var a7 = "Cat" && false;    // t && f returns false

// Logical OR
var o1 =  true || true;     // t || t returns true
var o2 = false || true;     // f || t returns true
var o3 =  true || false;    // t || f returns true
var o4 = false || (3 == 4); // f || f returns false
var o5 = "Cat" || "Dog";    // t || t returns Cat
var o6 = false || "Cat";    // f || t returns Cat
var o7 = "Cat" || false;    // t || f returns Cat

For more information, see: Mozilla Developer Network on Logical Operator Expressions

Upvotes: 1

thefourtheye
thefourtheye

Reputation: 239463

function(path, limit) {
    var ref = firebaseRef(path);
    limit && (ref = ref.limit(limit));   // Important
    return $firebase(ref);
}

The Important line, can be written like this

if (limit) {
    ref = ref.limit(limit);
}

But if you wanted to write it like the first way, you would have done,

ref = limit && ref.limit(limit)

This has one problem, when limit is Falsy && immediately returns the evaluated Falsy value of limit, so ref is Falsy now. You wouldn't have wanted this, I believe.

At the end of the day, as a programmer, readability and maintainability of the code of the code what we write matters. So, I would recommend using an explicit if check, which I mentioned at the beginning of the answer.

Note: Also, as noted by others, the first multiply should have been like this

var multiply = function(arg1, arg2) {
    arg1 || (arg1 = 0);
    arg2 || (arg2 = 0);
    return arg1 * arg2;
}

Even better, I would have written it like this

var multiply = function(arg1, arg2) {
    return (arg1 || 0) * (arg2 || 0);
}

Upvotes: 2

Related Questions