ช่วงนี้ฉันทำงานกับ JavaScript, React และ Redux มาได้ระยะหนึ่งแล้ว และโดยเฉพาะอย่างยิ่ง ฉันกำลังพยายามเขียนโปรแกรมเชิงฟังก์ชันบางอย่าง

สิ่งหนึ่งที่ทำให้ฉันประทับใจในตอนแรกคือวิธีการใช้ฟังก์ชัน likefetch ในฟังก์ชันอื่นๆ ราวกับว่าเป็นส่วนหนึ่งของภาษา เช่นนี้:

const getData = url => {
  fetch(url).then(...)
}

ตอนนี้ก็เป็นเรื่องปกติจนกระทั่งคุณต้องการทดสอบ getData ขณะออฟไลน์ เป็นต้น ในโลกเชิงวัตถุ ฉันจะฉีดการพึ่งพาของฉันผ่าน Constructor ของฉัน ฉันจะทำสิ่งที่คล้ายกันในรูปแบบการใช้งานได้อย่างไร

มีคุณลักษณะของภาษาเชิงฟังก์ชันที่ฉันพบว่าเหมาะสมกับการเรียกเก็บเงินเป็นอย่างดี: currying.

การสรุปโดยสรุปหมายถึงการเปลี่ยนฟังก์ชันที่รับพารามิเตอร์ N ไปเป็นฟังก์ชันที่รับพารามิเตอร์ครั้งละ 1 ตัว N ครั้ง:

sum(1,2)
curriedSum(1)(2)

ยิ่งไปกว่านั้น ES2015 (ข้อกำหนด JavaScript ล่าสุด คุณสามารถเรียนรู้เพิ่มเติมได้ใน เอกสารประกอบของ Babel) ให้น้ำตาลเชิงวากยสัมพันธ์แก่เราเพื่อสร้างฟังก์ชัน curried:

const curriedSum = a => b => a + b
// equivalent to
const curriedSum = a => {
  return b => {
    return a + b
  }
}

ตอนนี้ กลับไปที่ตัวอย่างเริ่มต้น เราอาจเขียน

const getData = fetch => url => {
  fetch(url).then(...)
}
// at some point we initialize getData
startTheAppWhichKnowsTheUrl(getData(fetch))
// in your tests
const mockFetch = () => Promise.resolve(createMockedBody())
getData(mockFetch)(url) // will use the mocked response body

เรากำลังทำอะไรที่นี่? เรากำลังประกาศ getData ให้เป็นฟังก์ชันที่ยอมรับพารามิเตอร์หนึ่งชื่อ fetch และส่งคืนฟังก์ชันอื่นที่ยอมรับพารามิเตอร์อื่น url

ยิ่งฉันใช้รูปแบบนี้มากเท่าไร ฉันก็ยิ่งพบว่ามันมีประโยชน์ในทุกสถานการณ์ที่เราไม่สามารถควบคุมลายเซ็นที่จำเป็นสำหรับฟังก์ชันที่เรากำลังส่งผ่านไปได้ ซึ่งโดยทั่วไปจะสรุปไปที่ฟังก์ชันเกือบทุกฟังก์ชันที่ยอมรับการเรียกกลับในพารามิเตอร์ของมัน . ตัวอย่างเช่น: Array.map ยอมรับการเรียกกลับซึ่งมีค่าซ้ำและดัชนีเป็นพารามิเตอร์ และส่งกลับค่าที่แก้ไข จะเป็นอย่างไรหากเราต้องการระบุดัชนีที่แน่นอนเพื่อแก้ไขสำหรับการโทรกลับ เราสามารถบรรลุผลได้ด้วยวิธีนี้:

const zeroAtIndex = zeroIndex => (val, index) => {
  if (zeroIndex === index) {
    return 0
  }
  return val
}
[1,2,3].map(zeroAtIndex(2)) // [1,2,0]

หรือหากคุณใช้ React เหมือนที่ฉันทำเมื่อเร็วๆ นี้:

const onOnClick = (onItemSelected, item) => () => {
  onItemSelected(item)
}
const ItemView = ({onItemSelected, item}) => {
  return (
    <button onClick={onClick(onItemSelected, item)}>
      {item.title}
    <button>
  )
}

JavaScript มีการพัฒนาค่อนข้างเร็ว และสำหรับ ES2015 ก็ได้รับไวยากรณ์ที่น่าทึ่ง ซึ่งเราสามารถใช้เพื่อเขียนโค้ดที่สวยงามและบำรุงรักษาได้ นี่เป็นสไตล์การเขียนโค้ดในชีวิตประจำวันของฉันจริงๆ และฉันคิดว่ามันจะมีประโยชน์อย่างมากทุกครั้งที่ฉันเริ่มเขียนโค้ดเชิงฟังก์ชันล้วนๆ