问题
I read through the redux-actions tutorial, and am confused by their use of (what I believe to be) destructuring. Below is an example (increment
& decrement
are both functions returned by the createAction
function).
const { createAction, handleActions } = window.ReduxActions;
const reducer = handleActions(
{
[increment]: state => ({ ...state, counter: state.counter + 1 }),
[decrement]: state => ({ ...state, counter: state.counter - 1 })
},
defaultState
);
Here's another example of this being used:
const { createActions, handleActions, combineActions } = window.ReduxActions;
const reducer = handleActions(
{
[combineActions(increment, decrement)]: (
state,
{ payload: { amount } }
) => {
return { ...state, counter: state.counter + amount };
}
},
defaultState
);
Can somebody explain what's happening in those lines? In simplified terms, I just see {[function]: () => ({})}
, and don't understand what this does.
回答1:
That's indeed a computed property name, but with a twist - a function is used as a key, not a string.
It might look confusing until you remember that each function can be safely cast to string - the result is that function's source code. And that's exactly what happens here:
function x() {}
const obj = { [x]: 42 };
console.log( obj[x] ); // 42
console.log( obj[x.toString()] ); // 42, key is the same actually
console.log( Object.keys(obj) ); // ["function x() {}"]
The advantage of such approach is that you don't need to create additional keys - if you have a function reference, you already have one. In fact, you don't even have to have a reference - it's enough to have a function with the same source:
const one = () => '';
const two = () => '';
console.log(one === two); // false apparently
const fatArrObj = { [one]: 42 }
fatArrObj[two]; // 42, take that Oxford scholars!!
The disadvantage is that function is cast to string each time it's used as key - a (supposedly minor) performance hit.
To add some fun, this is valid object literal:
{
[null]: null, // access either with [null] or ['null']
[undefined]: undefined,
[{ toString: () => 42 }]: 42 // access with, you guess it, 42 (or '42')
}
... and this one might go into book of weird interview questions:
const increment = (() => { let x = 0; return () => ++x })();
const movingTarget = { toString: increment };
const weirdObjectLiteral = { [movingTarget]: 42 };
console.log( weirdObjectLiteral[movingTarget] ); // undefined
来源:https://stackoverflow.com/questions/52123007/what-does-this-array-style-destructuring-on-a-function-do-in-es6