Reputation: 5487
I am reviewing some Javascript code and stumbled upon a syntax that I didn't knew. The application is a React and Redux one, though I think this is plain Javascript.
The syntax I'm concerned with is the { f1(), f2(), ... }
argument of combineReducers()
.
This is the syntax:
combineReducers({
Reducer1,
Reducer2,
...
});
ReducerN is a function, i.e.:
const Reducer1 = (state = INITIAL_STATE, action) => {
// ...
};
I get { f1(), ... }
creates an object where the function name is the key and the function itself is the value, so in a browser console I tried the following:
a = () => { console.log(1) }
b = () => { console.log(2) }
o = {a, b}
and if I print o
:
{a: ƒ, b: ƒ}
a: () => { console.log(1) }
b: () => { console.log(2) }
__proto__: Object
But if I try to initialize o
in a single operation:
o = { () => return 1 }
or
o = { function y() { return 1 }}
they both give a syntax error.
It's the first time I see an object created with that syntax: What kind is that? Where can I find its reference?
Upvotes: 0
Views: 60
Reputation: 72256
{ f1() }
is very different than { f1 }
.
The latter is a shorthand of { f1: f1 }
which is an object having the key 'f1'
(a string) associated to the value f1
(a function). The function is not executed.
In the first example f1()
is a function call. The function f1
is executed and the value it returns is used instead. But because you didn't provide a key to associate the value with and because f1()
is a value that does not have a name (it is an expression that needs to be evaluated in order to get its value), JS cannot produce an object out of it.
{ f1 }
can be evaluated at the compile time and turned into { f1: f1 }
.
{ f1() }
cannot be evaluated at the compile time. The value of f1()
is available only at the run time.
This is why { f1() }
is invalid code.
If you need to call f1
and use the value it returns to create an object you can do it this way:
const x = { f1: f1() }
This is the same thing as:
const v = f1();
const x = { f1: v }
Upvotes: 0
Reputation: 2451
As said previously,
combineReducers({
Reducer1,
Reducer2,
...
});
is equivalent to this in plain ES5:
combineReducers({
Reducer1: Reducer1,
Reducer2: Reducer2,
...
});
and combineReducers
is concerned only with the values of the object passed in. The first form is just a shorthand for defining properties with the same name as the value. This is the reason you cannot use anonymous functions in this form. To define function members on classes and objects, you can use the following form:
class Foo {
foo() { console.log('foo'); }
bar = () => console.log('bar')
}
const a = new Foo();
a.foo();
a.bar();
const b = {
foo() { console.log('foo'); }
bar: () => console.log('bar')
};
b.foo();
b.bar();
When transpiling to plain ES5, this will generate the following:
"use strict";
var Foo = /** @class */ (function () {
function Foo() {
this.bar = function () { return console.log('bar'); };
}
Foo.prototype.foo = function () { console.log('foo'); };
return Foo;
}());
var a = new Foo();
a.foo();
a.bar();
var b = {
foo: function () { console.log('foo'); },
bar: function () { return console.log('bar'); }
};
b.foo();
b.bar();
Upvotes: 1