Erick Hupin
Erick Hupin

Reputation: 172

ES6 default parameters: values not assigned properly

I'm playing with ES6 Default parameters, and I got a weird behaviour.

Here is an short example of the problem:

function test(firstValue, secondValue=5){
  console.log("firstValue: " + firstValue);
  console.log("secondValue: " + secondValue);
  console.log("----------")
}

test(2, secondValue = 3)
test(secondValue = 3)

And its output:

firstValue: 2
secondValue: 3
----------
firstValue: 3
secondValue: 5
----------

In the second case, I expected firstValue: undefined and secondValue: 3. Is this behaviour normal. Do I miss something?

Upvotes: 1

Views: 108

Answers (3)

cubbuk
cubbuk

Reputation: 7920

You want to do destructuring I guess:

function test({firstValue, secondValue = 5} = {}){
  console.log("firstValue: " + firstValue);
  console.log("secondValue: " + secondValue);
  console.log("----------")
}

test() // prints firstValue: undefined, secondValue: 5
test({}) // prints firstValue: undefined, secondValue: 5
test({firstValue: 2}) // prints firstValue: 2, secondValue: 5
test({secondValue: 3}) // prints firstValue: undefined, secondValue: 3

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074276

When you do

test(2, secondValue = 3)

you are, in effect, doing this:

secondValue = 3
test(2, 3)

The first part (secondValue = 3) creates a global variable called secondValue thanks to The Horror of Implicit Globals.* It has nothing to do with the secondValue parameter in your function. JavaScript doesn't have named arguments. (E.g., you can't say "here's the value for secondValue" when making a call except by putting it in the right position in the argument list. If you want to specify the names when making the call, you can use destructuring as cubbuk points out, which isn't really named arguments but can serve the same sort of purpose.)

The second part (passing 3 into test) happens because the result of an assignment is the value that was assigned (so secondValue = 3 sets secondValue to 3 and results in the value 3, which is then passed into test).

To call test with 3 for secondValue, just do that. E.g.:

test(2, 3);

If you want to leave the second one off, the default will be used:

test(2);

Example:

function test(firstValue, secondValue=5){
  console.log("firstValue: " + firstValue);
  console.log("secondValue: " + secondValue);
  console.log("----------");
}

test(2, 3);
test(2);


* (that's a post on my anemic little blog)

Upvotes: 5

Nina Scholz
Nina Scholz

Reputation: 386568

You are using a global variable without declaring it. The assignment generates a global variable and does not affect the variables of function test. These local variables are independent form the calling scope.

function test(firstValue, secondValue=5){
  console.log("firstValue: " + firstValue);
  console.log("secondValue: " + secondValue);
  console.log("----------")
}

var secondValue; // with declaration
console.log(secondValue);
test(2, secondValue = 3)
test(secondValue = 3)
console.log(secondValue);

Upvotes: 1

Related Questions