loading...

I just learned: JavaScript tricks you into thinking it has keyword arguments.

calin92540842 profile image PDS OWNER CALIN (Calin Baenen) ・1 min read

JavaScript does have keyword arguments, the syntax is:

let func = function func({}) {
    console.log(a);
    console.log(b);
};

func({a: "hi", b: "bye"}); //
func(a="hi",b="bye"); // hi    \n    bye

There's only two major downfalls,

  1. kwargs can not come after varargs
  2. The variables defined in kwargs are saved globally




With that learning out of the way, is there anyone who has enough knowledge on these artificial 'kwarg' replacements to help answer the following:.

Is there a way to stop kwarg variables from being saved globally?
I want to save the variables from the kwarg in the function, but it saves them globally. Is there any way to stop that?

Thanks
Cheers!

Discussion

markdown guide
 

Those aren't keyword arguments, you are creating variables in the global scope and passing them to the function. a=1 is just saying window.a = 1 and then passing 1 to your function. a is now a variable in global scope.

 

Agreed. This is one of the few JavaScript quirks that I feel is extremely dangerous and very confusing for beginners.

As a follow up for OP to explain why this works, a JavaScript function accepts any argument that are valid expressions (ie. can be evaluated to a value). For example, try this:

console.log(a = 1) // 1
console.log(const a = 2) // error!

This is because a = 1 is an expression which evaluates to the value 1, while const a = 2 is not. As such, calling a function like func(a = 1) is perfectly valid JavaScript and is akin to calling func(1).

It is also perfectly valid JavaScript to declare variables without any of the keywords like var, let, or const. However, like Mike has said, whenever you do this, you are polluting your global scope with these variables, and this will lead to a myriad of problems. I will strongly recommend not to declare variables like this.

 

As far as I understand JavaScript, what's happening here is the compiler is creating statements that equate to the following:

var a = "hi";
var b = "bye";
func("hi", "bye");

And then you're using the variables in the function because they're global, like this:

var a = "hi";
var b ="bye";
let func = () => {
    console.log(a);
    console.log(b);
};

The way I would do this that I think would accomplish what you're trying is to pass an object in that has the same properties, create a default inside of the function, then Object.assign them together. Something like this:

let func = (obj) => {
    let params = {a: "Hello", b: "Goodbye"};
    Object.assign(params, obj);
    const {a, b} = params;
    console.log(a);
    console.log(b);
}

func(); // Hello\n Goodbye
func({a: "Hola", b: "Adios"}); // Hola\nAdios
 

There is a simpler way:

let func = ({ a = 'Hello', b = 'Goodbye' } = {}) => {
  console.log(a)
  console.log(b)
}

func() // Hello, Goodbye
func({}) // also: Hello, Goodbye
func({ a: 'Hola' }) // Hola, Goodbye
func({ a: 'Hola', b: 'Adios' }) // Hola, Adios