• 函数柯里化


    高阶函数:如果一个函数的参数或返回值仍为函数,则该函数为高阶函数。如Promise()、setTimeout()、Array.prototype.map()等
    函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式
    示例:假设一个求和函数sum如下所示

    function sum(a,b,c){
    	return a+b+c
    }
    console.log(sum(1,2,3)); // 6
    
    • 1
    • 2
    • 3
    • 4

    将其修改成以下形式就是函数的柯里化

    function sum(a){
    	return function(b){
    		return function(c){
    			return a+b+c
    		}
    	}
    }
    console.log(sum(1)(2)(3)); // 6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    函数柯里化让代码更复杂了,那一般什么场景用函数柯里化呢?
    答:当参数不方便一次性都传递过去的时候可以考虑用函数柯里化

    举例:假设要实现如下功能,点击登录会有弹出框,显示当前输入的用户名和密码。以下示例用了React框架去实现
    在这里插入图片描述
    不用柯里化的时候,要针对多个输入字段写它自己的onChange回调函数(saveUsername和savePassword),saveUsername和savePassword代码重复率很高,如果有多个输入字段的值需要实时记录到组件的state中,那就要写多个字段onChange对应的回调函数,但是这些回调函数的区别就是setState存储的字段不同。这样代码会导致代码冗余度比较高

    <body>
    	<!-- 准备好一个“容器” -->
    	<div id="test"></div>
    	
    	<!-- 引入react核心库 -->
    	<script type="text/javascript" src="../js/react.development.js"></script>
    	<!-- 引入react-dom,用于支持react操作DOM -->
    	<script type="text/javascript" src="../js/react-dom.development.js"></script>
    	<!-- 引入babel,用于将jsx转为js -->
    	<script type="text/javascript" src="../js/babel.min.js"></script>
    
    	<script type="text/babel">
    		//创建组件
    		class Login extends React.Component{
    
    			//初始化状态
    			state = {
    				username:'', //用户名
    				password:'' //密码
    			}
    
    			//保存用户名到状态中
    			saveUsername = (event)=>{
    				this.setState({username:event.target.value})
    			}
    
    			//保存密码到状态中
    			savePassword = (event)=>{
    				this.setState({password:event.target.value})
    			}
    
    			//表单提交的回调
    			handleSubmit = (event)=>{
    				event.preventDefault() //阻止表单提交
    				const {username,password} = this.state
    				alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
    			}
    
    			render(){
    				return(
    					<form onSubmit={this.handleSubmit}>
    						用户名:<input onChange={this.saveUsername} type="text" name="username"/>
    						密码:<input onChange={this.savePassword} type="password" name="password"/>
    						<button>登录</button>
    					</form>
    				)
    			}
    		}
    		//渲染组件
    		ReactDOM.render(<Login/>,document.getElementById('test'))
    	</script>
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    有没有办法让这些输入性质的标签的onChange回调共用一个回调函数,这个回调函数接收该标签绑定的字段,这样就可以根据标签绑定的字段修改state中相应的字段值了。但是onChange接收一个回调函数并且这个回调函数只有一个参数event。该如何解决这个问题呢?如下有2种解决方式

    方法一:使用柯里化
    onChange,onSubmit等需要赋值给它一个函数,函数柯里化使得函数执行的返回值仍是函数,就可以实现这样的需求。saveFormData返回一个函数,这个函数是onChange的回调,所以这个回调函数第一个参数是event,因为外层函数已经传入了datatype,所以在这个函数里可以同时使用字段类型dataType和event参数。

    <body>
    	<!-- 准备好一个“容器” -->
    	<div id="test"></div>
    	
    	<!-- 引入react核心库 -->
    	<script type="text/javascript" src="../js/react.development.js"></script>
    	<!-- 引入react-dom,用于支持react操作DOM -->
    	<script type="text/javascript" src="../js/react-dom.development.js"></script>
    	<!-- 引入babel,用于将jsx转为js -->
    	<script type="text/javascript" src="../js/babel.min.js"></script>
    
    	<script type="text/babel">
    		//创建组件
    		class Login extends React.Component{
    			//初始化状态
    			state = {
    				username:'', //用户名
    				password:'' //密码
    			}
    
    			//保存表单数据到状态中
    			// saveFormData返回一个函数,这个函数是onChange的回调,所以这个回调函数第一个参数是event,因为外层函数已经传入了datatype,所以在这个函数里可以同时使用字段类型dataType和event参数
    			saveFormData = (dataType)=>{
    				return (event)=>{
    					// 注意不要写成{dataType:event.target.value},因为dataType是变量不是字符串的字段名
    					this.setState({[dataType]:event.target.value})
    				}
    			}
    
    			//表单提交的回调
    			handleSubmit = (event)=>{
    				event.preventDefault() //阻止表单提交
    				const {username,password} = this.state
    				alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
    			}
    			render(){
    				return(
    					<form onSubmit={this.handleSubmit}>
    						用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/>
    						密码:<input onChange={this.saveFormData('password')} type="password" name="password"/>
    						<button>登录</button>
    					</form>
    				)
    			}
    		}
    		//渲染组件
    		ReactDOM.render(<Login/>,document.getElementById('test'))
    	</script>
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    方法二:不用柯里化
    直接给onChange赋值一个回调函数,在回调函数体里调用saveFormData('字段名', event),这样也实现了传入要修改的字段名的效果

    <body>
    	<!-- 准备好一个“容器” -->
    	<div id="test"></div>
    	
    	<!-- 引入react核心库 -->
    	<script type="text/javascript" src="../js/react.development.js"></script>
    	<!-- 引入react-dom,用于支持react操作DOM -->
    	<script type="text/javascript" src="../js/react-dom.development.js"></script>
    	<!-- 引入babel,用于将jsx转为js -->
    	<script type="text/javascript" src="../js/babel.min.js"></script>
    
    	<script type="text/babel">
    		//创建组件
    		class Login extends React.Component{
    			//初始化状态
    			state = {
    				username:'', //用户名
    				password:'' //密码
    			}
    
    			//保存表单数据到状态中
    			saveFormData = (dataType,event)=>{
    				this.setState({[dataType]:event.target.value})
    			}
    
    			//表单提交的回调
    			handleSubmit = (event)=>{
    				event.preventDefault() //阻止表单提交
    				const {username,password} = this.state
    				alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
    			}
    			render(){
    				return(
    					<form onSubmit={this.handleSubmit}>
    						用户名:<input onChange={event => this.saveFormData('username',event) } type="text" name="username"/>
    						密码:<input onChange={event => this.saveFormData('password',event) } type="password" name="password"/>
    						<button>登录</button>
    					</form>
    				)
    			}
    		}
    		//渲染组件
    		ReactDOM.render(<Login/>,document.getElementById('test'))
    	</script>
    </body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
  • 相关阅读:
    MySQL(3)
    rust编程-rust所有权理解(chapter 4.2 引用实质是借用)
    嵌入式音频软件开发之协议时序图分析方法
    动环监控系统的主要功能,动环监控系统的监控对象有哪些
    【Android动画】之Tween动画 (渐变、缩放、位移、旋转)
    SIMetrix导入MOS管参数的另一种方法
    logback-spring.xml配置文件标签(超详解)
    设备远程维护与人工现场维护相比优势在哪?
    Ngnix优化
    数字时代,VR虚拟展会打造全渠道同步营销新模式
  • 原文地址:https://blog.csdn.net/qq_59200309/article/details/136586602