10

Ideally I want to be able to write something like:

function a( b ) {
    b.defaultVal( 1 );
    return b;
}

The intention of this is that if b is any defined value, b will remain as that value; but if b is undefined, then b will be set to the value specified in the parameter of defaultVal(), in this case 1.

Is this even possible?

Ive been toying about with something like this:

String.prototype.defaultVal=function(valOnUndefined){
    if(typeof this==='undefined'){
        return valOnUndefined;
    }else{
        return this;
    }
};

But I'm not having any success applying this kind of logic to any variable, particularly undefined variables.

Does anyone have any thoughts on this? Can it be done? Or am I barking up the wrong tree?

Jimmery
  • 9,783
  • 25
  • 83
  • 157
  • technically, I can't see how the prototype would work, since it'd have to be a string BEFORE the initialization could be called, so it'd never be undefined in the first place – Marc B Sep 13 '12 at 15:32
  • The prototype code I put up there doesnt work (why Im toying about with it) - it would be ideal if I could access the prototype object of an undefined variable. But Im not sure if this is possible. – Jimmery Sep 13 '12 at 15:37

3 Answers3

12

Why not use the default operator:

function someF(b)
{
    b = b || 1;
    return b;
}

Job done! Here's more info about how it works.

Just as a side-note: your prototype won't work, because you're augmenting the String prototype, whereas if your variable is undefined, the String prototype doesn't exactly apply.

To be absolutely, super-duper-sure that you're only switching to the default value, when b really is undefined, you could do this:

var someF = (function(undefined)//get the real undefined value
{
    return function(b)
    {
        b = b === undefined ? 1 : b;
        return b;
    }
})(); // by not passing any arguments
Deqing
  • 14,098
  • 15
  • 84
  • 131
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • 2
    consider this: `function someF(b){ b = b || true; return b; }` this call: `someF()` would return `true`, but this call: `someF(false)` would return `true` - so this method is flawed when working with boolean values. – Jimmery Sep 13 '12 at 15:41
  • 2
    Kind of. This works for strings and various other objects, it does not however work for all objects, such as booleans and ints. 0, false, etc. will be overwritten by your "default". I wouldn't refer to `||` as "the default operator", as it really isn't. It's an inclusive OR, and you should probably be aware of the full effects of it before using it like this. – Vala Sep 13 '12 at 15:43
  • 2
    I've updated my answer to avoid issues with falsy values being passed to the function causing unexpected return values. It's a but much, though. You could use `function foo(b){ b = b === undefined : b;`, too. But `undefined` can be reassigned (`undefined = 1`), which would break the function, that's why I'm using a closure – Elias Van Ootegem Sep 13 '12 at 15:50
9

Well the most important thing to learn here is if a variable is undefined you, by default, do not have any methods available on it. So you need to use a method that can operate on the variable, but is not a member/method of that variable.

Try something like:

function defaultValue(myVar, defaultVal){
    if(typeof myVar === "undefined") myVar = defaultVal;
    return myVar;
}

What you're trying to do is the equivalent of this:

undefined.prototype.defaultValue = function(val) { }

...Which for obvious reasons, doesn't work.

BLSully
  • 5,929
  • 1
  • 27
  • 43
  • 2
    This. You could also shorten it a little if desired: `return myVar !== undefined ? myVar : defaultVal;` – Vala Sep 13 '12 at 15:45
  • @Thor84no, no, because `undefined` may be overriden. But there is even shorter valid option: `return myVar !== void 0 ? myVar : defaultValue;`. – Victor Dombrovsky Jan 05 '17 at 14:26
  • 4
    @VictorDombrovsky Perhaps, but if you feel the need to guard against overriding of `undefined` you're working in code hell. – Vala Jan 05 '17 at 15:48
3

While the two answers already provided are correct, the language has progressed since then. If your target browsers support it, you can use default function parameters like this:

function greetMe(greeting = "Hello", name = "World") {
  console.log(greeting + ", " + name + "!");
}

greetMe(); // prints "Hello, World!"
greetMe("Howdy", "Tiger"); // prints "Howdy, Tiger!"

Here are the MDN docs on default function parameters.

Noel
  • 3,288
  • 1
  • 23
  • 42