高階函式_函式柯里化

高階函式(定義)

如果一個函式符合下面兩個規範,就是高階函式:

  • 如果A函式,接收的引數是一個函式,那麼A就是一個高階函式(比如陣列方法arr.map()接收的就是一個處理item的函數了)

  • 如果A函式,呼叫的返回值依然是一個函式,那麼A也稱為是高階函式(常見的高階函式:Promise、setTimeout、arr.map()等等陣列內建的方法)

函式柯里化(定義)

通過函式呼叫繼續返回函式的方式,實現多次接收引數最後統一處理的函式編碼形式

(有點像回撥地獄的感覺,就是一直then)

一個柯里化的例子:

class Login extends React.Component {
state = {
username: '',
password: ''
}

saveFormData = (dataType) => {
console.log(dataType);
return event => {
this.setState({[dataType] : event.target.value})
}
}
render() {
return (
<form action="http://www.atguigu.com" onSubmit={this.handleSubmit}>
使用者名稱:<input onChange={this.saveFormData('username')} type="text" name="username"/>
密碼:<input onChange={this.saveFormData('password')} type="password" name="password"/>
<button>登入</button>
</form>
)
}
}
例子疑問一:

為什麼通過 this.saveFormData('username') 這樣不是會把返回值給onChange函式嗎?

回答:如果saveFormData()函式返回的是一個函式的話就可以

解釋:

  • 因為this.saveFormData('username'),把‘username’傳遞作為saveFormData的形參dataType

  • 返回給onChange的函式相當於

onChange={ event => { this.setState({[username] : event.target.value}) } } 

所以這個event其實就是這個input的元素物件了

例子疑問二:

為什麼用{[dataType] : event.target.value}

解釋:

  • 假如我們寫的是dataType : event.target.value,其實就相當於是給this.state.dataType賦值了,但是dataType它要表示的是username或者是password,而不是dataType這個變數

比如說 obj = { a: 2} ,可以通過obj.a獲取,也可以通過obj[a]獲取

而下面其實省略了一點東西,完整的是 this[dataType],因為我們把dataType通過引數傳遞進來了

它是this的一個屬性了,我們訪問dataType的時候,其實預設的是通過this.dataType也就是通過

this當前作用域來找到對應的變數的

因為dataType是我們傳遞過來的形式引數,所以通過this.dataType可以獲取到我們的形式引數了

沒有柯里化的例子

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 action="http://www.atguigu.com" 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>
)
}
}