[JS] const function parameters

Don’t know if this has been suggested before but it seems like a relatively obvious feature to have.

let creates a mutable binding, and const creates an immutable binding. However function parameters are always implicity mutable, i.e.:

function foo(param) // 'param' is implicitly mutable
    console.log("param = " + param);
    param = 5;  // this is allowed
    console.log("param = " + param);

Why not allow const in function parameters?

function foo(const param) // 'param' is immutable
    console.log("param = " + param);
    param = 5;  // throws, cannot modify const parameter
    console.log("param = " + param);

In the second example using param would be treated the same as if it were defined as a local variable with const instead of let.

This would provide the same benefits as const for function parameters, i.e. readability, indicating intent, avoiding accidental modification of parameters, etc.

This would be extended to default parameters, e.g.

function foo(const param = 0)
    // ...

Perhaps for consistency let should then also be allowed to explicity indicate a mutable parameter? e.g.

function foo(let param)
    // ...

I don’t see why not, considering this already exists for variables in general. Having default values would be incredibly useful, even more so than the (im)mutablility.

Default parameter values are already specified/supported in ES6, I was only referring to the ability to use const or let simultaneously with a default parameter.

Aren’t parameters already bound to their scope? Making them let by default. The only change here would be allowing const to be used, but IMO this doesn’t seem like a truly beneficial addition to make it worth implementing.

To me, it’s more of a consistency issue. Why do we allow const for variables declared inside the function, but not parameters passed into the function?

1 Like

What other language let’s this happen? I don’t recall any that do.

Also, what is the actual benefit this provides to developers writing programs? Can you provide an example where a program is made tangibly better by this addition that currently is problematic in some way.

I know at least one other language with similar features - C++ allows const on both variable declarations and parameters, e.g.:

const int x = 0;
x = 1;  // not allowed

void myfunction(const int x = 0)
    x = 1; // not allowed

In C++ this is more typically used with references or pointers, e.g.:

int* const y = &x; // const pointer to modifiable int
const int* y = &x; // modifiable pointer to const int
const int& y = &x; // (implicitly const) reference to const int

Any of the above work with both variable declarations and parameters. As @jhpratt mentioned I think it is useful for JS to be consistent about this too. In JS, const o = obj is probably most analogous to int* const, i.e. a const reference to a modifiable object.

The benefit to developers is the same as using const for variable declarations, except now you can use it for parameters. For example I like using const instead of let as a language-enforced way of saying “this won’t be changed”, which makes it quicker and easier to understand existing code. By allowing this for function parameters the same benefits can apply there, e.g. I can see a function parameter is const so I don’t need to figure out if the function body changes it anywhere. Also arguably it is better style to avoid modifying function parameters.

1 Like

I’m not sure what the consistency is other than consistent with one other language’s features. Right now, JS is absolutely consistent that parameters are let style definitions, always no matter your context. This would then introduce, “what type of parameter am I working with?” confusion.

I’d like to see a tangible case where this is adding benefit to an application.

1 Like

I don’t think that qualifies as consistent. Currently function parameters and variable declarations work differently: parameters are always let, but with variables you get to choose between let and const. Why aren’t they both the same?

It’s really the same reasons as const was added for variable declarations, which was compelling enough to get specified. Take any example using const, and just imagine a function parameter instead of variable declaration. Those are the cases!

1 Like

I also feel this would be super useful. I’ve emailed the W3C/TC-39 coordination list to get more information and maybe some help! https://lists.w3.org/Archives/Public/public-script-coord/2017JanMar/0010.html

Here is the response we got. Anyone want to be a hero and kick off the proposal there?

On 2 Feb 2017, at 9:50 pm, David Bruant wrote:

Hi Marcos,

Le 30/01/2017 à 06:22, Marcos Caceres a écrit : Also, where should developers go to propose JS language features? For features that fall under the ECMAScript umbrella (like the syntax change you’re suggesting), I think the place to go to is https://github.com/tc39/proposals where among other things you can review existing tracked proposals.

The process is described here: https://tc39.github.io/process-document/

Thanks, we will follow up there.

Any proposal would start at stage 0, obviously.

Yep; we will seek guidance there about the stages.

Is this just a matter of writing a summary like this?: https://gist.github.com/dherman/1c97dfb25179fa34a41b5fff040f9879

Yep, and we even have a great champion for it (Mark Miller said he could champion it!).

Then it would be a matter of seeing if we can do a Stage-0 transpile in Babel or one of the other transpilers to prove it works. That should be fairly trivial.

Just a quick note, I think we also want to cover the destructuring case:

function foo( const {x , y}, z){}
(const {x , y}, z) => {}
1 Like

Is this submitted or being tracked at a different place now? I really find it annoying that function arguments can’t be const. It seems like an oversight to me. I don’t want to have to trust myself not to modify variables.

There has been a discussion 9 years ago 1. That’s a long time. It’s probably best to start a new one (and ask for a TC39 champion for this feature).