我如何阅读此多参数功能

时间:2019-04-09 17:43:13

标签: javascript ecmascript-6

如何阅读和解释函数的以下行:

const canUser = (permission) => (permissions) => (guideSlug) => {

这是完整功能:

const canUser = (permission) => (permissions) => (guideSlug) => {
  if (!permissions) return false;

  const globalPermissions = permissions['*'] || {};
  const guidePermissions = permissions[guideSlug] || {};
  return globalPermissions[permission] || guidePermissions[permission] || false;
};

修改

如果我有这样的对象:

export const checks = {
  canInvite: canUser('invite'),
}

我正在将canInvite导入我的组件中,然后运行该函数,并为其提供一个guideSlug(字符串)来运行该函数。它可以工作并签出,但我不完全确定如何从const canUser函数定义

理解它的作用。

这里的任何澄清都会有所帮助。谢谢!

2 个答案:

答案 0 :(得分:1)

from enum import Enum class States(Enum): COMPLETED_STATE = 'completed' DEPENDENCY_WAIT_STATE = 'dependency_wait' FAILED_NO_RERUN_STATE = 'failed_no_rerun' IGNORED_STATE = 'ignored' RUNNING_STATE = 'running' NEVER_RUN_STATE = 'never_run' ON_HOLD_STATE = 'on_hold' def __hash__(self): return hash(self.value) def __str__(self): return self.value def __eq__(self, other): if type(self) == type(other): return self.value == other.value return self.value == other def __get__(self, *args, **kwargs): return self.value Map = { States.ON_HOLD_STATE: [States.NEVER_RUN_STATE], States.DISABLED_STATE: [States.NEVER_RUN_STATE], States.RUNNING_STATE: [States.DEPENDENCY_WAIT_STATE, States.ON_HOLD_STATE, States.NEVER_RUN_STATE], States.IGNORED_STATE: [States.RUNNING_STATE, States.NEVER_RUN_STATE] } print(Map[States.RUNNING_STATE]) // ['dependency_wait', 'on_hold', 'never_run'] print(Map['running']) // ['dependency_wait', 'on_hold', 'never_run'] print(States.RUNNING_STATE == 'dependency_wait') // False print(States.RUNNING_STATE == 'running') // True print(States.RUNNING_STATE == States.RUNNING_STATE) // True if 'running' in States: print "Found" // Does not gets printed if States.RUNNING_STATE in States: print "Found here" // Does not gets printed 可以宽松地写为const foo = function(x) { return x + 1 }。后者称为arrow function

所以

const foo = x => x + 1

相同
const canUser = (permission) => (permissions) => (guideSlug) => {
  if (!permissions) return false;

  const globalPermissions = permissions['*'] || {};
  const guidePermissions = permissions[guideSlug] || {};
  return globalPermissions[permission] || guidePermissions[permission] || false;
};

这被称为partial applicationcurrying,两者有点相同,我不确定这是正确的术语。

在这种情况下很有用...

const canUser = function(permission) {
  return function(permissions) {
    return function (guideSlug) {
      if (!permissions) return false;

      const globalPermissions = permissions['*'] || {};
      const guidePermissions = permissions[guideSlug] || {};
      return globalPermissions[permission] || guidePermissions[permission] || false;
    }
  }
};

正如您所看到的,代码中有很多const foo = (x, y) => { /* something to be done with x and y */ } let x = foo(a,b); let y = foo(a,c); let z = foo(a,d); ,这些代码是重复性的并且可读性较差。通过以下方式编写可解决问题...

a

这种模式的另一个优点是,您可以将const foo = x => y => { /* something to be done with x and y */ } let fooA = foo(a); // fooA is the `y => {}` function with `x = a` "partially applied" let x = fooA(b); let y = fooA(c); let z = foo(a)(d); // you can still write it like this 传递给其他函数,或者将其存储在fooA的抽象形式中,例如a a const somethingRelevantToA = { foo: foo(a), bar: "some other prop of

如果您想要" }fooA之类的东西,并且它们之间有共同点,例如...

,那么您就在重用逻辑。

fooB

因此基本上,不是在分别编写const foo = x => y => { /* piece of code independent of x (this is being reused) */ /* piece of code dependent only on y or x and y both */ } fooA,而是在编写fooB,从而重用了逻辑。

答案 1 :(得分:0)

这段代码可以在ES5中这样重写:

var canUser = function canUser(permission) {
  return function (permissions) {
    return function (guideSlug) {
      if (!permissions) return false;
      var globalPermissions = permissions['*'] || {};
      var guidePermissions = permissions[guideSlug] || {};
      return globalPermissions[permission] || guidePermissions[permission] || false;
    };
  };
};

这称为currying。作为this article中的状态,是将具有多个参数的函数转换为一系列仅具有一个参数的函数的过程。

假设您具有在某处定义的权限和guideSlug,

var permissions = {'accounts':{'invite': true}, '*':{'home': '/'}};
var guideSlug = 'accounts';

您可以使用以下命令调用该函数:

canUser('invite')(permissions)(guideSlug)

var permissions = {'accounts':{'invite': true}, '*':{'home': '/'}};
var guideSlug = 'accounts';

var canUser = function(permission) {
  return function(permissions) {
    return function (guideSlug) {
      if (!permissions) return false;

      var globalPermissions = permissions['*'] || {};
      var guidePermissions = permissions[guideSlug] || {};
		console.log(globalPermissions);
console.log(guidePermissions);
      return globalPermissions[permission] || guidePermissions[permission] || false;
    }
  }
};

console.log(canUser('invite')(permissions)(guideSlug));

我在您的示例中注意到的一件事是,它仅调用第一个函数,这意味着它将在您在此处调用时将函数返回给checks.canInvite:

export const checks = {
  canInvite: canUser('invite'),
}