这种数组式的函数解构在 ES6 中有什么作用?
What does this array-style destructuring on a function do in ES6?
我通读了 redux-actions
tutorial,并对他们对(我认为是)解构的使用感到困惑。下面是一个示例(increment
和 decrement
都是 createAction
函数返回的函数)。
const { createAction, handleActions } = window.ReduxActions;
const reducer = handleActions(
{
[increment]: state => ({ ...state, counter: state.counter + 1 }),
[decrement]: state => ({ ...state, counter: state.counter - 1 })
},
defaultState
);
这是使用的另一个例子:
const { createActions, handleActions, combineActions } = window.ReduxActions;
const reducer = handleActions(
{
[combineActions(increment, decrement)]: (
state,
{ payload: { amount } }
) => {
return { ...state, counter: state.counter + amount };
}
},
defaultState
);
有人可以解释一下这些行中发生了什么吗?简单来说,我只看到{[function]: () => ({})}
,不明白这是做什么的。
这确实是一个 computed property name,但有一个转折 - 函数用作键,而不是字符串。
在您记得每个函数都可以安全地转换为字符串之前,它可能看起来很混乱 - 结果就是该函数的源代码。这正是这里发生的事情:
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() {}"]
这种方法的优点是您不需要创建额外的键 - 如果您有一个函数引用,那么您已经有了一个。事实上,您甚至不必有参考 - 具有相同来源的函数就足够了:
const one = () => '';
const two = () => '';
console.log(one === two); // false apparently
const fatArrObj = { [one]: 42 }
fatArrObj[two]; // 42, take that Oxford scholars!!
缺点是每次将函数用作键时都会将其转换为字符串 - 性能下降(据推测是次要的)。
为了增加一些乐趣,这是有效的对象字面量:
{
[null]: null, // access either with [null] or ['null']
[undefined]: undefined,
[{ toString: () => 42 }]: 42 // access with, you guess it, 42 (or '42')
}
...而这个问题可能会出现在奇怪的面试问题书中:
const increment = (() => { let x = 0; return () => ++x })();
const movingTarget = { toString: increment };
const weirdObjectLiteral = { [movingTarget]: 42 };
console.log( weirdObjectLiteral[movingTarget] ); // undefined
我通读了 redux-actions
tutorial,并对他们对(我认为是)解构的使用感到困惑。下面是一个示例(increment
和 decrement
都是 createAction
函数返回的函数)。
const { createAction, handleActions } = window.ReduxActions;
const reducer = handleActions(
{
[increment]: state => ({ ...state, counter: state.counter + 1 }),
[decrement]: state => ({ ...state, counter: state.counter - 1 })
},
defaultState
);
这是使用的另一个例子:
const { createActions, handleActions, combineActions } = window.ReduxActions;
const reducer = handleActions(
{
[combineActions(increment, decrement)]: (
state,
{ payload: { amount } }
) => {
return { ...state, counter: state.counter + amount };
}
},
defaultState
);
有人可以解释一下这些行中发生了什么吗?简单来说,我只看到{[function]: () => ({})}
,不明白这是做什么的。
这确实是一个 computed property name,但有一个转折 - 函数用作键,而不是字符串。
在您记得每个函数都可以安全地转换为字符串之前,它可能看起来很混乱 - 结果就是该函数的源代码。这正是这里发生的事情:
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() {}"]
这种方法的优点是您不需要创建额外的键 - 如果您有一个函数引用,那么您已经有了一个。事实上,您甚至不必有参考 - 具有相同来源的函数就足够了:
const one = () => '';
const two = () => '';
console.log(one === two); // false apparently
const fatArrObj = { [one]: 42 }
fatArrObj[two]; // 42, take that Oxford scholars!!
缺点是每次将函数用作键时都会将其转换为字符串 - 性能下降(据推测是次要的)。
为了增加一些乐趣,这是有效的对象字面量:
{
[null]: null, // access either with [null] or ['null']
[undefined]: undefined,
[{ toString: () => 42 }]: 42 // access with, you guess it, 42 (or '42')
}
...而这个问题可能会出现在奇怪的面试问题书中:
const increment = (() => { let x = 0; return () => ++x })();
const movingTarget = { toString: increment };
const weirdObjectLiteral = { [movingTarget]: 42 };
console.log( weirdObjectLiteral[movingTarget] ); // undefined