jerrypy
jerrypy

Reputation: 139

How does Javascript declare function parameters?

function func(x = y, y = 2) { 
    return [x, y];
}

func(); // ReferenceError: y is not defined
func(1); // [1, 2]

As the code above implied, there is a hidden TDZ in the function parameters scope, which explains why the code below fails:

function func(arg) {
    let arg = 1; // SyntaxError: Identifier 'arg' has already been declared
}

So function parameters should be declared with let, but what confused me is :

function func(arg) {
    var arg = 1;
    console.log(arg); // 1
}

this code works fine.

Why you can redeclare variables using var? How does Javascript declare function parameters?


edit: I know exactly you can't use let to redeclare a variable. The question here is if function parameters is declared using let, so:

function func(arg) {
    var arg = 1;
}

is like:

let arg; // arg parameter declares here
var arg = 1; // func body 

and why this can run without an exception?

Upvotes: 0

Views: 521

Answers (7)

MinusFour
MinusFour

Reputation: 14423

Parameter bindings does not exactly follow the same behavior as the ones declared with let.

1) Parameter bindings get created before var bindings. var doesn't create bindings that already exist, so there's never a problem there. let however creates bindings after var.

2) There's an early error on all productions that create a scope that has it as a rule that no lexical binding can occur when there's already a variable declaration with the same name.

Upvotes: 0

Bergi
Bergi

Reputation: 665130

there is a hidden TDZ in the function parameters scope

Yes indeed. Have a look here for some more examples.

How does Javascript declare function parameters?

As parameters - see here for a step-by-step explanation. They're neither the same as let nor the same as var, they have their own semantics. ES6, which introduced default initialisers, gave them the same TDZ limitations as in let to catch more programmer mistakes.

Why you can redeclare variables using var?

Because until ES5, redeclaring a variable was not an error condition, and this behaviour needed to be preserved to not break the web. It could only be introduced for new features, like let and const - or argument lists that use default initialisers, try function x(bar, bar) {} vs function x(bar, bar=1){}.

Upvotes: 3

linasmnew
linasmnew

Reputation: 3977

The reason that is, is because of something that people in the JavaScript community refer to as "hoisting" when you do var arg = 1 that gets translated into var arg; arg = 1; however if var has already been defined as is the case here because of the function parameter, then the compiler tries to be helpful and ignores subsequent re-declarations instead of throwing an error... which is probably an unexpected behaviour, and hasn't been followed through with the new let variable declaration, however, it has to stay there for backwards compatibility reasons.

Upvotes: 1

M0nst3R
M0nst3R

Reputation: 5293

let is added more recently and with it, an error throw was introduced that manifests when you try to declare a variable that involves let twice. This does not happen with var which will simply replace the old value, unless the variable has been already declared with let.

function func(arg) {
    let arg = 1; // not ok, because `let` knows that `arg` is being redeclared
}

function func(arg) {
    var arg = 1; // ok, because `var` will just replace the value of `arg`
}

function func() {
    let arg = 0;
    var arg = 1; // not ok, because `let` declared `arg` already
}

Here is a link to the MDN for let which explains the feature.

Upvotes: 0

Josh
Josh

Reputation: 1647

So var is legacy syntax and ideally you probably want to avoid using it.

Instead using let for variables that can be reassigned, and const for constants.

var also has global scope where as let and const are limited to the scope they are in.

Upvotes: 0

Cerbrus
Cerbrus

Reputation: 72947

This isn't necessarily related to the function's arguments.

This will throw an error as well:

function func() {
    var arg = 1;
    let arg = 2
    console.log(arg); // 1
}

func();

You just can't use let to re-declare a variable, while var isn't that strict: var doesn't try to re-declare the variable if it's already declared. It just assigns the new value.

For more information on the specifics of let, see this MDN page on the let statement.

Upvotes: 1

guest271314
guest271314

Reputation: 1

The first example will not throw an error a value if an argument is passed to func call.

var does not have the same scope as let or const.

Upvotes: -2

Related Questions