1

I know that it is bad practice to write code like this:

var createBox = function(width, height, margin){
    alert("Margin is set to " + margin);
    //margin is undefined in this context or why?
    var margin = margin || 2;
    alert("Margin is now " + margin);
}
createBox(0,0,0);

But can someone please explain, why margin is always set to 2?

Is it because it is undefined in the direct context of initializing a variable with the same name inside the function?

edit: sorry, I got the problem wrong ...

Please give a small hint :) Regards, Tom

6
  • Thanks for editing, forgot to post the code :) Commented Oct 24, 2010 at 11:52
  • 2
    It is not possible that your second example alerts 0. Put it on jsbin or jsfiddle and show us if you really think that's what happens, but it won't happen. (Are you sure that you didn't leave "margin" in the second alert instead of "margin2"?) Commented Oct 24, 2010 at 12:05
  • Lies! Easy explanation: the second code also alerts 2: jsbin.com/erehu3 Commented Oct 24, 2010 at 12:05
  • What exactly is "as expected" in your case? Commented Oct 24, 2010 at 12:07
  • I was wrong, my fault. Did see some js-ghosts or something ... Commented Oct 24, 2010 at 12:14

4 Answers 4

3

The || operator in JavaScript returns the value of the first operand if the first operand is truthy. Otherwise it returns the value of the second operand. It doesn't return 1/0, or true/false, as in some other languages.

Therefore when the margin argument holds a falsy value, such as 0 or undefined, it will return 2, since these are both falsy values in JavaScript.

The falsy values in JavaScript are: an empty string "", the null value, a value of 0, the NaN value, the boolean value false, and also undefined.

What you describe is a very common idiom in JavaScript. In fact the || operator is sometimes called the default operator1. You can use it to assign default values to variables when they are undefined. The problem in this case is that since 0 is a valid argument, the default operator is not behaving as required. You may want to do the following instead:

margin = typeof margin === 'undefined' ? 2 : margin;

1 Douglas Crockford: The Elements of JavaScript Style - Part 2 - Idioms.

Sign up to request clarification or add additional context in comments.

5 Comments

Yes Daniel, but why is margin undefined? if I use f.e. var margin2 = margin || false; margin2 is set to 0 as expected
@shapeshifta: Updated my answer... margin is not undefined. It is set to 0, which is also a "falsy" in JavaScript. Therefore, the || operator returns the second operand: 2 and assigns it to margin.
I think you are right in a way, but that is not the answer for my problem I think. Just compare: var margin = margin || 2 //2; var margin2 = margin || 2; //0 -> this is my question :)
@shapeshifta it is the answer to your problem.
to much coffee, to little sleep ... sorry!
3

If you call createBox(0,0,0), then margin is 0 (which has the truth value of false), so the expression margin || 2 becomes 0 || 2 which is equal to 2.

4 Comments

but if I write var margin2 = margin || 2, margin2 is set to 0 as expected ;)
@shapeshifta no it is not set to 2. That definitely will not happen if margin is zero.
Not for me. margin2 outputs 2 on the last alert.
Oh I am so sorry, I mixed it up ... :(
2

0 evaluates to false List of Truthy Values

Comments

1
// This function creates a new box by receiving three parameters
var createBox = function(width, height, margin){
    // Output the margin of the box, zero in current case
    alert("Margin is set to " + margin);
    // If the margin is zero or undefined, '' set default value to 2
    var margin = margin || 2;
    // Output the new value of the margin which is 2
    alert("Margin is now " + margin);
}
// here will show Margin: 0 after that Margin: 2
createBox(0,0,0);

// here will show Margin: 1 after that Margin: 1
createBox(0,0,1);

// here will show Margin: 3 after that Margin: 3
createBox(1,2,3);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.