43

What I want to do is to use as many immutable variables as possible, thus reducing the number of moving parts in my code. I want to use "var" and "let" only when it's necessary.

This won't work:

function constParam(const a){
    alert('You want me to '+a+'!');
}

Any ideas?

Damjan Pavlica
  • 21,431
  • 6
  • 55
  • 65
shal
  • 2,110
  • 3
  • 15
  • 25

8 Answers8

54

Function parameters will stay mutable bindings (like var) in ES6, there's nothing you can do against that. Probably the best solution you get is to destructure the arguments object in a const initialisation:

function hasConstantParameters(const a, const b, const c, …) { // not possible
    …
}
function hasConstantParameters() {
    const [a, b, c, …] = arguments;
    …
}

Notice that this function will have a different arity (.length), if you need that you'll have to declare some placeholder parameters.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
  • 20
    This is actually an interesting solution for that. If it wasn't so ugly, I would start using it. – Karel Bílek Oct 01 '15 at 13:44
  • 2
    How about `function hasConstantParameters(...args) { const [a, b] = args; };`? – Bugs Bunny Jun 27 '17 at 08:58
  • 3
    @BugsBunny That's pretty much the same. However, I don't like the introduction of another identifier (`args`), and I did deliberately put no parameters in the usual place but moved everything into the `const` declaration. – Bergi Jun 27 '17 at 09:26
  • 1
    Making it with dynamic arity ruins the idea of strictness, but yes, this one answers the question correctly! – shal Feb 05 '18 at 12:33
  • @shal The arity is not dynamic, it's just no longer available as the `.length` property of the function object – Bergi Feb 05 '18 at 13:17
  • @Bergi, you're right, what I mean is that now IDEs like WebStorm cannot infer the number of arguments, to help you with function invocation verification (unless you use JSDoc) – shal Feb 08 '18 at 12:19
  • @Bergi sure, but `arguments`, like `this`, don't exist for short functions `() => {}` – Hashbrown Feb 01 '20 at 01:38
  • @Hashbrown In an arrow function, you can also use a rest parameter to get an array of arguments. – Bergi Feb 01 '20 at 13:52
  • I meant that's what bugs was getting at when you replied `@BugsBunny That's pretty much the same.`; [`If you're writing ES6 compatible code, then rest parameters should be preferred.`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments) – Hashbrown Feb 01 '20 at 15:18
  • Today, I learned what [arity](https://en.wikipedia.org/wiki/Arity) means :-) – Mawg says reinstate Monica Mar 31 '21 at 09:18
14

You can't make a parameter const. Use it as the initial value of a local variable:

function constParam(a) {
    const const_a = a;
    ...
}

Note also that const is only supported in Internet Explorer as of IE11. See this compatibility table

Barmar
  • 596,455
  • 48
  • 393
  • 495
2

For immutable structures I believe you're looking for Immutable.js.


As @Andreas_Gnyp is saying, until ES6 there is no let / const in JavaScript. (Nor there will be function(const a) {...} once ES6 is out and fully supported.) If you want to use const, you can either implement your own const feature, or start using ES6 notation with help of some third party ES6-to-ES5 compiler, such as Babel.

However, bear in mind that const in ES6 notation does not make the variable immutable. E.g. const a = [1, 2]; a.push(3); is a completely valid program and a will become [1, 2, 3]. const will only prevent you from reassigning a, so that you can't do a = [] or a = {} or whatever once const a = [1, 2]; already defined (in that particular scope).

function hasConstantParameters(...args) {
    const [a, b] = args;
}

Immutable.js will make sure that, when you define var a = fromJS([1, 2]); and pass a as a function parameter, in the receiving function a.push(3) will not affect a. Is this what you wanted to achieve?

Bugs Bunny
  • 1,992
  • 1
  • 23
  • 27
  • 6
    This answer has nothing to do with my question. I asked about constant parameters, not about privacy of class members. – shal Oct 14 '15 at 07:27
1

There is no way to force a parameter to be immutable in JavaScript. You have to keep track of that yourself.

Just write in a style where you happen not to mutate variables. The fact that the language doesn't provide any facilities to force you to do so doesn't mean that you can't still do it anyway.

  • 5
    @QuentinRoy References? Es6 provides ways of declaring constant values, but there is no way to declare a *function parameter* as constant. You can write "function(){ const a = ...; ...}", but you can't write "function(const a){...}". – Logan R. Kearsley Feb 14 '16 at 18:29
  • You're right sorry I read to fast. I thought you were talking about variable instead of parameters. – Quentin Roy Feb 15 '16 at 10:19
1

We can use ES6 destructuring to create constants from params

function test(...args) {
   const [a, b, c] = args;
}
Drenai
  • 7,125
  • 5
  • 40
  • 67
-1

This is what I do:

Instead of:

function F(const a, const b, const c, const d, const e, const f, const g){ // Invalid Code
    // lorem
    // ipsum
}

..Use:

function F(){const[a, b, c, d, e, f, g] = arguments;
    // lorem
    // ipsum
}
Pacerier
  • 76,400
  • 86
  • 326
  • 602
-2

First of all, there are no constants in JS (until ECMAScript 6 proposal). You will have to use var to construct something like that. If you want to have "private" areas in your JS code, you use one of the features of the language, which are scopes.

So, e.g, go like this:

 var kindaConstant = function(){
   var donttouchthis
   ... do something with it
   return whateveryouvedonewithit
 }

In this case donttouchthis is not that easily mutable from "outside".

Andreas Gnyp
  • 1,106
  • 1
  • 14
  • 21
  • Constants do exist in javascript and are supported by modern browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const – Rob M. May 18 '15 at 23:56
  • You're link starts with the words "This is an experimental technology," ... It is true, that some browser support constants. You should be lucky working for a project, which lets you choose the browser ... ;-) – Andreas Gnyp May 19 '15 at 00:14
  • It's no longer experimental – Xenos Feb 09 '18 at 10:22
-3
function wrapper(i){
    const C=i
    return new Function("a","b", "return a+b+"+C)    
}

f100 = wrapper(100) //ƒ anonymous(a,b/*``*/) {return a+b+100} 
f100(1,2) //OUTPUT 103

f200 = wrapper(200) //ƒ anonymous(a,b/*``*/) {return a+b+200} 
f200(1,2) //OUTPUT 203