首页 > 解决方案 > 使用闭包返回函数作为参数

问题描述

这是我的 JS 小提琴的链接:https ://jsfiddle.net/apasric4/v1qkmgyu/1/

function inputCheck(input) {
  if (input.name==="email") {
    console.log("email")
    return isValidEmail
  } else if (input.name==="password") {
    return isValidPassword
    console.log("pass")
  } else if (input.name==="userName") {
    return isValidUserName
    console.log("user")
  }
}


function isValidEmail (email) {
  return /^[^@]+[@][^@.]+\.[a-z]+$/.test(email)
}

function isValidPassword(pass) {
  return /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/.test(pass)
}

function isValidUserName(user) {
  return /^[a-zA-Z0-9]+([_ -]?[a-zA-Z0-9])*$/.test(user)
}


function validation(e) {
  e.preventDefault()
  inputs.forEach(input=> createListener(inputCheck(input)))
}



function createListener(validator) {
  return (e)=> {
    const inputValue=e.target.value;
    const valid=validator(inputValue)
    console.log(valid)
  }
}

我正在尝试使用闭包创建表单验证。我正在努力使我的代码尽可能高效。

我想遍历每个输入元素(而不是单独选择每个元素),并对每个元素应用一个事件侦听器。inputCheck 函数将根据每个输入的 name 属性返回一个验证器函数,createListener 函数获取 inputCheck 返回的值,该值将是特定类型的验证器,然后出于测试目的,console.log 为真或假。

到目前为止,在 inputCheck 函数中工作的唯一 if 分支是第一个与 name 属性 email 关联的分支。如果我在其他输入元素中键入值并提交表单,则另一个 if 分支将不起作用。

谁能告诉我哪里出了问题以及如何改进我的代码?

我是闭包的新手,所以我知道这个问题对你们大多数人来说似乎相对简单。

标签: javascriptscopeclosures

解决方案


我可以观察到两件事:

首先,就像@VLAZ 指出的那样, inputCheck 中的两个console.log 实际上没有执行,因为它们是在返回之后放置的。

第二,createListener并不validation完全正确。createListener返回一个带有一个参数的函数。validationforEach 不记录任何内容,因为createListener返回一个函数,这里没有函数执行。

e的论点还有另一个问题createListener。似乎您将其视为一个事件,但根据您的实现,只有一个事件,即表单提交事件。所以,我建议稍微修改一下这两个函数:

function validation(e) {
  e.preventDefault()
  inputs.forEach(input=> createListener(inputCheck(input))(input))
}



function createListener(validator) {
  return (e)=> {
    const inputValue=e.value;
    const valid=validator(inputValue)
    console.log(valid)
  }
}

然后,控制台根据每个输入字段的输入值打印出真假。请检查输出是否是您的意图https://jsfiddle.net/jqgbefhw/


推荐阅读