2

我通读了redux-actions教程,并且对他们使用(我认为是)解构感到困惑。下面是一个示例(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]: () => ({})},不明白这是做什么的。

4

1 回答 1

6

这确实是一个计算的属性名称,但有一个扭曲 - 一个函数用作键,而不是字符串。

在您记得每个函数都可以安全地转换为字符串之前,它可能看起来令人困惑——结果就是该函数的源代码。这正是这里发生的事情:

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
于 2018-08-31T22:11:04.707 回答