如何在Javascript ES6中将switch语句作为函数参数传递?

时间:2017-02-26 22:40:17

标签: ecmascript-6 redux

如何在Javascript中将switch语句作为函数参数传递?

我想用Redux库做到这一点:

const agendaPointsReducer = function (state = initialState, action) {
  return Object.assign({}, state, switch (action.type) {
    case OPEN_AGENDA_POINT: {
      state.modal_is_open = true,
      state.point_id = action.id
    }
    case CLOSE_AGENDA_POINT: {
      state.modal_is_open = false
    }
  })
}

但是我收到了意外的令牌错误。我知道这可能在Coffeescript中有用,有没有办法在Javascript es6中做到这一点?

6 个答案:

答案 0 :(得分:3)

一种可能性是将它包装成这样的函数:

const agendaPointsReducer = function (state = initialState, action) {
  return Object.assign({}, state, (() => {
    switch (action.type) {
      case OPEN_AGENDA_POINT: {
        state.modal_is_open = true,
        state.point_id = action.id
      }
      case CLOSE_AGENDA_POINT: {
        state.modal_is_open = false
      }
    }
  })())
}

答案 1 :(得分:2)

switch语句不是Javascript中的表达式。在Coffeescript中,一切都是表达式(红宝石)。因此,没有办法做到这一点。此外,在刚刚显示的示例中,没有理由,因为switch语句只是修改已经传递的state变量。

答案 2 :(得分:1)

因此,Object.assign()将您传递给目标对象的对象的属性复制。因此,您需要传递的是具有可以从中复制的属性的对象。

如果您要尝试做的是创建一个具有基于当前执行的switch语句属性的对象(这是我对您尝试做的事情的猜测),那么I&I #39;建议您在调用Object.assign()之前创建源对象并将该对象传递给它。

按照我在此处显示的方式进行操作将避免任何会改变传入对象的副作用(这就是为什么我们在本地对象的switch语句中设置属性,而不是{{1} } object):

state

答案 3 :(得分:1)

我认为你真正想要做的是这样的事情:

createSession(sessionName:any)
{
    return this._http.post( this._sessionUrl + "/create/"+sessionName.sessionName,{}).map((res: Response) => res)
    .do(data => console.log('Session created'))
     .catch(this.handleError);
}

答案 4 :(得分:1)

除了针对您问题的特定答案之外,我还想为您提供更一般的答案。

要将switch语句传递给函数,您需要将其转换为表达式。有两种不同的方法可以实现这一目标。

在函数

中换行switch

const apply = f => x => f(x);

const enumerate = apply(x => {
  switch (x.constructor) {
    case Number: {
      return inc(x);
    }

    case String: {
      return succ(x);
    }

    default: throw TypeError();
  }
});

const inc = x => x + 1;

const succ = x => String.fromCharCode(x.charCodeAt(0) + 1);

console.log("enum 1:", enumerate(1)); // 2

console.log("enum a:", enumerate("a")); // "b"

通过这种方法,我使用apply作为一个小辅助功能。它使调用代码更具可读性,例如Object.assign({}, state, apply(x => {/* switch statement */}) (action.type))

switch本身作为一个函数

const caseOf = (...pairs) => x => {
  let g;

  pairs.some(([guard, f], i) => guard(x) 
   ? (g = f, true)
   : false);

  return g(x);
}

const inc = x => x + 1;

const succ = x => String.fromCharCode(x.charCodeAt(0) + 1);

const enumerate = caseOf(
  [x => x.constructor === Number, x => x + 1],
  [x => x.constructor === String, x => String.fromCharCode(x.charCodeAt(0) + 1)]
);

console.log("enum 1:", enumerate(1));

console.log("enum a:", enumerate("a"));

caseOf是正常函数,更高阶函数更精确。您可以在允许表达式的任何地方应用它。

解构分配

解构分配是一个非显而易见的优势,两种方法都超过了正常的switch语句。您可以在没有其他变量的情况下应用解构赋值:

const apply = f => x => f(x);

const sqr = x => x * x

const xs = [2],
 ys = [];

console.log(
  sqr(apply(([x]) => { // <= destructuring assignment
    switch (x) {
      case undefined: return 0;
      default: return x;
    }
  }) (xs))
);

console.log(
  sqr(apply(([x]) => { // <= destructuring assignment
    switch (x) {
      case undefined: return 0;
      default: return x;
    }
  }) (ys))
);

const caseOf = (...pairs) => x => {
  let g;

  pairs.some(([guard, f], i) => guard(x) 
   ? (g = f, true)
   : false);

  return g(x);
}

const sqr = x => x * x;

const isAssigned = x => x !== undefined && x !== null;

const always = x => _ => x;

const xs = [5],
 ys = [];
 
console.log(
  caseOf(
    [([x]) => isAssigned(x), sqr], // <= destructuring assignment
    [always(true), always(0)] // default case
  ) (xs)
);

console.log(
  caseOf(
    [([x]) => isAssigned(x), sqr], // <= destructuring assignment
    [always(true), always(0)] // default case
  ) (ys)
);

我希望有所帮助。

答案 5 :(得分:1)

我认为daniel_franzjfriend00给出的答案是最好,最直接的解决方案。但考虑替代方案仍然很有趣:)

尝试将switch逻辑存储在Map中,我尝试了一些乐趣。它可能有许多缺点(对于一个,你不能通过省略break来链接案例),并且它使得过于复杂的东西,所以我想我们必须把它看作只是一个探索而不是“这就是我在真实项目中的表现方式”......

方法:

  • 为每个Map创建一个case,一个条目
  • 每个条目都有case作为键
  • 每个条目都有一个函数,它将所需的结果作为值
  • 返回
  • 对于未定义的情况,Map的{​​{1}}会返回getItem,我们也会将其包含在函数中

代码:

null