【问题标题】:call javascript object method using partial arguments from outer scope使用外部范围的部分参数调用 javascript 对象方法
【发布时间】:2021-01-15 21:01:07
【问题描述】:

我有一个 getValidators 函数,它返回一个带有验证器方法的对象:

export function getValidators()  {

  return {
    required: (node, value, [mark='', falsy=[undefined, '']]) => {
      const notValid = falsy.includes(value);
      return setNotValid(node, notValid, mark);
    },
    // ... other validator functions ...
  };
};

所有验证器函数都有三个参数:节点、值和数组:args

我可以运行验证器功能:

let validator = 'required';
let validators = getValidators()
let result = validators[validator](node, value, args);

但我喜欢使用来自某个外部范围的参数节点和值来运行下面修改后的验证器函数:

export function getValidators()  {

  return {
    required: ([mark='', falsy=[undefined, '']]) => {
      const notValid = falsy.includes(value);
      return setNotValid(node, notValid, mark);
    },
    // ...
  };
};

并喜欢如下图运行:

// ... node and value args passed in from outer scope ...?
let result = validators[validator](args);

更新:我不能使用getValidators(node, value),因为会首先调用 getValidators 来添加额外的验证器函数。

let validators = getValidators();
validators[method] = aValidatorFunc;
.....
.....
function runValidators() {
  .....
  // use the updated validators instance to run the validators
  for (let validator of .....) { 
     // node and value will change in this loop as well
     ... 
     let result = validators[validator](args);
  }
  ...
}

【问题讨论】:

  • 那么你的问题是什么?哪个部分不工作?你哪里有问题?
  • 如何从外部作用域传入(节点,值)?
  • 为什么不使用参数?这就是他们的目的。以及“外部作用域”到底是什么意思
  • 是的,这是可能的。 “nodevalue 来自某个外部范围” - 那么,来自 哪个 外部范围?它们目前在您修改的代码中根本不存在。

标签: javascript scope closures


【解决方案1】:

找到了一种使用bind(this)的解决方案:

let validators = getValidators();
validators[method] = aValidatorFunc;
.....
.....
function runValidators() {
  .....
  // use the updated validators instance to run the validators
  for (let validator of .....) { 
     // node and value will change in this loop as well
     ...
     const validatorFunc = validators[validator].bind({node, value})  // bind this
     // or with call with a given this as firtst argument: 
     // const validatorFunc = validators[validator].call({node, value}, args); 

     let result = validatorFunc(args);
  }
  ...
}

绑定我们不能使用箭头函数,所以要使用'this':

export function getValidators()  {

  return {
    required: function([mark='', falsy=[undefined, '']]) {  // function
      const notValid = falsy.includes(this.value);
      return setNotValid(this.node, notValid, mark);
    },
    // ...
  };
};

【讨论】:

    【解决方案2】:

    不知道这是否是您的意思,但您可以像这样从外部函数的范围内传递它们:

    export function getValidators(node, value)  { // Put them in the argument list here
      return {
        required: ([mark='', falsy=[undefined, '']]) => {
          const notValid = falsy.includes(value);
          return setNotValid(node, notValid, mark);
        },
        //...
      };
    };
    
    let validator = 'required';
    let validators = getValidators(node, value); // Pass your node and value to the outer function
    
    // Now call it like you wanted to call it:
    let result = validators[validator](args);
    

    【讨论】:

    • 是的,你说的很对。但是必须在节点值可用之前调用 getValidators。第一次调用用于添加动态验证器。
    • 那么请澄清您的问题。你的节点和价值从哪里来,你想什么时候把它们放在哪里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多