JS 命令式 宣告式 函式式 程式設計?
JS 命令式 宣告式 函式式 程式設計?
——煙雨仔的讀書筆記, 並沒有很深奧~
1. 命令式 和 宣告式 是啥?
命令式和宣告式是按照程式設計風格來劃分的.
宣告式有一個突出特點: 對執行結果的描述遠勝於執行過程.
相對地, 命令式的特點是: 關注達成目標的具體過程.
或許你還是很懵, 看下面的指令式程式設計例子.
const arr = ['h', 'e', 'l', 'l', 'o' ]
for(let i = 0; i < arr.length; i++) {
arr[i] = arr[i].toUpperCase()
}
console.log(arr)
在上面的例子中, 包含了完成這個任務的整個過程, 即遍歷整個陣列並轉換成大寫.
接下來看宣告式程式設計如何完成.
const arr = ['h', 'e', 'l', 'l', 'o']
const arrNew = arr.reduce((prev, cur) =>
prev += cur.toUpperCase(), '')
console.log(arrNew)
對於上述程式碼, 我們之所以明白它發生了什麼是由於看到 reduce 方法, 但具體遍歷處理的細節被抽象封裝到 reduce 內部, 我們並沒有看到它迴圈遍歷的過程.
簡單理解就是命令式程式碼的過程相當細節: 切塊, 去籽, 扔進攪拌機, 而宣告式程式碼描述的是具體結果: 西瓜, 榨成西瓜汁.
因此宣告式程式設計程式碼是可讀性更強的, 因為我們並不在意榨成西瓜汁的細節. React 框架採用的就是宣告式程式設計, render 函式呼叫來構建 DOM, 但 DOM 渲染的具體細節是被封裝的. 雖然看不到細節, 但我們看到 render 方法就清楚地知道這是在渲染元件.
2. JS 中的函式
JS 可以進行函數語言程式設計, 這意味著變數可以做的事情, 函式也可以.
是的, 接下來你需要謹記: “函式就是變數!”
- 可以像宣告變數那樣去宣告一個函式(函式表示式)
let fn = function(msg) { console.log(msg) }
- 函式就是變數! 因此可以新增到物件中
const obj = { msg: 'hello watermelon', foo (msg) { console.log(msg) } }
- 函式就是變數! 因此可以新增到陣列中
const arr = [ 'hello watermelon', msg => console.log(msg), 'hello world' ] arr[1](arr[0]) // hello watermelon
- 函式就是變數! 因此可以作為其他函式的引數傳遞
let foo = fn => fn('hello watermelon') foo(msg => console.log(msg)) // hello watermelon
- 函式就是變數! 因此可以作為其他函式的執行結果返回
const foo = arg1 => arg2 => console.log(arg1 + ' ' + arg2) const log = foo('hello')// log 是 foo 返回的函式 log('watermelon')
經過以上的瞭解, 煙雨仔相信你開始有一丁點了解了.
函數語言程式設計的核心概念
這部分偏理論, 以至於煙雨仔也有些迷惑…
不可變性
在函數語言程式設計中, 資料不可變, 資料是無法被修改的. 這意味著不能修改原始資料, 只能進行拷貝編輯. 關於如何拷貝這裡就不進行贅述.
純函式
純函式是一個返回結果只依賴輸入引數的函式. 我們需要明確以下幾點.
- 純函式至少需要接收一個引數, 並將引數當做不可變資料.
- 總是返回一個值或其他函式.
- 不會產生副作用, 即不會修改作用域外的變數.
以下是一個非純函式.
const person = {
name: 'mistrain',
age: 18,
hobby: 'watermelon'
}
function changeName() {
person.name = 'zongzi'
return person
}
changeName()
console.log(person)
// {name: 'zongzi', age: 18, hobby: 'watermelon'}
以上 changeName 函式是非純函式. 它並沒有接收引數, 也沒有返回一個值或其他函式, 並且修改了作用域外資料 person.
接下來看純函式.
const person = {
name: 'mistrain',
age: 18,
hobby: 'watermelon'
}
const newPerson = info => ({...info, name: 'zongzi'})
// 擴充套件運算子, 並修改部分物件屬性, 煙雨仔第一次用這種寫法, 妙~
console.log(newPerson(person))
// {name: 'zongzi', age: 18, hobby: 'watermelon'}
console.log(person)
// {name: 'mistrain', age: 18, hobby: 'watermelon'}
以上是一個純函式, 它實現了不改變 person, 得到一個新的 newPerson 物件, 因此沒有產生副作用.
資料轉換
由於函數語言程式設計中資料不可變性的存在, 有時往往需要將一種資料轉換成另一種資料副本來使用. ES6提供了一些高階函式使轉換副本的程式碼更加簡單.
高階函式
- 第一類是 reduce, map, filter等, 它們都將函式作為引數進行傳遞.
- 第二類是將函式作為返回值. 如柯里化(currying)就是通過在一個函式內返回另一個函式實現的.
這裡放一個問爛了的經典柯里化面試題, 在瞭解函數語言程式設計後, 重新來看這個題相信你會有不一樣的理解.
實現一個函式, 呼叫得到:
fn(1) = 1
fn(1, 2, 3) = 6
fn(1)(2, 3)(4, 5, 6) = 21
…
遞迴
魯迅先生說: “不懂資料結構的前端也可以是好前端.”(煙雨仔瞎編的)相信你懂遞迴是怎麼一回事, 即"自己呼叫自己". 這裡煙雨仔也不贅述了.
一些廢話
本篇是煙雨仔在學習《React 學習手冊》時的一些筆記. 畢竟理論的東西就是很容易忘記, 但確實很有用~
寫得很淺, 不正確的地方望諸位大佬指正.
相關文章
- 瞭解 JavaScript 函數語言程式設計 - 宣告式函式JavaScript函數程式設計函式
- JS 中的函式表示式和函式宣告你混淆了嗎?JS函式
- 宣告與函式、函式指標函式指標
- JavaScript函式宣告和函式表示式區別JavaScript函式
- 何時使用函式表示式與函式宣告函式
- 函式宣告和函式表示式的區別函式
- js表示式方式和函式語句方式宣告函式的區別JS函式
- EventEmitter:從命令式 JavaScript class 到宣告函式式的華麗轉身MITJavaScript函式
- JS變數宣告和函式宣告提升JS變數函式
- 命令式、宣告式、物件導向、函式式、控制反轉之華山論劍(上)物件函式
- 命令式、宣告式、函式式、物件導向、控制反轉之華山論劍(下)函式物件
- 函式表示式和函式宣告簡單介紹函式
- 06函式宣告函式
- 函式程式設計函式程式設計
- python函式程式設計 返回函式 匿名函式 裝飾器 偏函式Python函式程式設計
- React基礎:宣告式程式設計React程式設計
- (譯) 函式式 JS #2: 函式!函式JS
- 揚帆起航:從指令式程式設計到函式響應式程式設計程式設計函式
- scala 函式程式設計函式程式設計
- 函式程式設計之道函式程式設計
- JavaScript 函式宣告方式JavaScript函式
- 深入解析JS變數宣告和函式宣告提升JS變數函式
- 淺談JS變數宣告和函式宣告提升JS變數函式
- 函式響應式程式設計與RxSwift函式程式設計Swift
- Lambda表示式入門--函數語言程式設計與函式式介面函數程式設計函式
- 函式式思維和函數語言程式設計函式函數程式設計
- JavaScript進階系列01,函式的宣告,函式引數,函式閉包JavaScript函式
- javascript 的函式宣告與表示式對比JavaScript函式
- JavaScript函數語言程式設計之pointfree與宣告式程式設計JavaScript函數程式設計
- 函式設計函式
- Spring程式設計式和宣告式事務例項講解Spring程式設計
- 宣告式事務能否和程式設計式事務巢狀使用?程式設計巢狀
- js函式 函式自呼叫 返回函式的函式 (閉包)JS函式
- JS函式表示式——函式遞迴、閉包JS函式遞迴
- 不用任何賦值的程式設計稱為*函式式*程式設計賦值程式設計函式
- 【趣解程式設計】函式程式設計函式
- Windows 程式設計常用函式Windows程式設計函式
- [譯]函式式響應程式設計入門指南函式程式設計