JavaScript 中的高階函數是一種接受函數作為輸入或返回函數作為輸出的函數。高階函數可以用於創建抽象概念,例如柯里化、組合和管道。 ...
一、高階函數
JavaScript 中的高階函數是一種接受函數作為輸入或返回函數作為輸出的函數。它們提供了靈活的方式來處理函數,並允許把函數作為參數或返回值傳遞。它們是函數式編程的重要組成部分,並且可以提高代碼的可讀性和可維護性。
高階函數的一個常見用法是對數組進行操作,例如使用 map()
、reduce()
和 filter()
。這些函數允許您在數組上應用自定義的函數,並對數組的每個元素執行操作。
另一個常見的高階函數是回調函數。回調函數是一種被傳遞到另一個函數中的函數,併在某些事件發生時被調用。它們允許您創建代碼,該代碼在事件發生時自動執行。
另外,高階函數還可以用於創建抽象概念,例如柯里化、組合和管道。柯里化是一種將多個參數的函數轉換為一系列接受單個參數的函數的技術。組合是將多個函數組合成一個新函數的技術。管道是一種通過將函數的輸出作為下一個函數的輸入來鏈接多個函數的技術。
高階函數也可以與閉包結合使用。閉包是一種函數,它引用了定義它的作用域之外的變數。這使得您可以在函數外訪問函數內部的變數,並將變數保存在記憶體中以供以後使用。
高階函數是 JavaScript 編程的重要概念,具有很多用途,並且可以提高代碼的複雜性。學習如何使用高階函數,並將其與其他技術結合起來,可以使您的代碼更加強大和高效。
一個常見的 JavaScript 高階函數示例是 Array.prototype.map()
:
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map(function(number) {
return number * 2;
});
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
在這個例子中,我們創建了一個數組,然後使用 map()
函數對數組中的每個元素進行操作。我們傳遞了一個回調函數,該回調函數接受一個數字,並返回該數字的兩倍。
另一個常見的高階函數示例是 Array.prototype.reduce()
:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce(function(total, number) {
return total + number;
}, 0);
console.log(sum); // 15
在這個例子中,我們使用 reduce()
函數對數組中的所有元素進行操作。我們傳遞了一個回調函數,該回調函數接受當前的總和和數字,並返回新的總和。
這些示例說明瞭高階函數的強大功能,以及如何將其與其他技術(例如回調函數)結合起來,以實現複雜的操作。
二、使用高階函數實現函數柯里化
柯里化是一種高階函數的技術,可以將多個參數的函數轉換為只有一個參數的函數。這可以使我們在需要的時候再傳遞其他參數,並逐步構建出完整的函數。
以下是 JavaScript 使用高階函數實現柯里化的示例:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(null, args);
} else {
return function(...args2) {
return curried.apply(null, args.concat(args2));
};
}
};
}
function add(a, b, c) {
return a + b + c;
}
const curriedAdd = curry(add);
const add5 = curriedAdd(5);
console.log(add5(10, 15)); // 30
在這個例子中,我們創建了一個 curry()
函數,該函數接受一個函數作為參數,並返回一個新函數。該新函數使用 apply()
方法應用所有參數,如果傳遞的參數數量不夠,則返回一個新的函數,該函數將傳遞的參數與當前的參數合併。
然後,我們使用 curry()
函數對 add()
函數進行柯里化,並創建了一個只接受一個參數的函數,該參數為 5。我們可以使用此函數來逐步構建出完整的函數,並使用最後兩個參數計算結果。
三、使用高階函數實現組合函數
組合函數是一種將多個函數結合起來以創建新函數的技術。在 JavaScript 中,可以使用高階函數實現組合函數。
以下是使用高階函數實現組合函數的示例:
function compose(f, g) {
return function(x) {
return f(g(x));
};
}
function double(x) {
return x * 2;
}
function add(x) {
return x + 1;
}
const composed = compose(add, double);
console.log(composed(3)); // 7
在這個例子中,我們創建了一個 compose()
函數,該函數接受任意數量的函數作為參數,並返回一個新函數。
然後,我們使用 compose()
函數將 double()
和 add()
函數組合在一起,並使用組合函數對數字 3 進行計算。因此,先調用 double(3)
,再調用 add(6)
,最後得到結果 7。
以下是另一種使用高階函數實現組合函數的示例:
function compose(...fns) {
return function(arg) {
return fns.reduceRight((result, fn) => fn(result), arg);
};
}
function double(x) {
return x * 2;
}
function add(x) {
return x + 1;
}
const composed = compose(double, add);
console.log(composed(3)); // 8
在這個例子中,我們創建了一個 compose()
函數,該函數接受任意數量的函數作為參數,並返回一個新函數。該新函數使用 reduceRight()
函數對所有函數進行組合,並對給定的參數進行計算。
然後,我們使用 compose()
函數將 double()
和 add()
函數組合在一起,並使用組合函數對數字 3 進行計算。因此,先調用 add(3)
,再調用 double(4)
,最後得到結果 8。
四、使用高階函數實現管道
管道是一種將多個函數連接起來以進行順序計算的技術。在 JavaScript 中,可以使用高階函數實現管道。
以下是使用高階函數實現管道的示例:
function pipe(...fns) {
return function(arg) {
return fns.reduce((result, fn) => fn(result), arg);
};
}
function double(x) {
return x * 2;
}
function add(x) {
return x + 1;
}
const piped = pipe(add, double);
console.log(piped(3)); // 8
在這個例子中,我們創建了一個 pipe()
函數,該函數接受任意數量的函數作為參數,並返回一個新函數。該新函數使用 reduce()
函數對所有函數進行管道,並對給定的參數進行計算。
然後,我們使用 pipe()
函數將 add()
和 double()
函數管道在一起,並使用管道函數對數字 3 進行計算。因此,先調用 add(3)
,再調用 double(4)
,最後得到結果 8。
五、組合函數和管道的區別
管道和組合函數都是高階函數的應用,但是它們有著明顯的不同:
-
實現方式:管道是通過將多個函數連接起來,依次對數據進行處理,而組合函數則是通過將多個函數組合成一個函數。
-
計算順序:管道函數的計算順序是從左到右,而組合函數的計算順序是從右到左。
-
結構:管道函數的結構是一維的,每一步的結果都是下一步的輸入;而組合函數的結構是二維的,一個函數的結果可以作為另一個函數的輸入。
因此,管道和組合函數都是高階函數的重要應用,在不同的場景中使用它們都有著獨特的優勢。
作者:yuzhihui
出處:https://www.cnblogs.com/yuzhihui/p/17100954.html
聲明:歡迎任何形式的轉載,但請務必註明出處!!!
-
GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 作者: 葉金榮 文章來源:GreatSQL社區原創 MySQL 8.0版本計劃 MySQL 8.0開始採用快速迭代開發模式,基本上是每隔3個月就發佈一個 ...
-
SqlServer屬於商業資料庫,不可能像Mysql等資料庫一樣,去解析相關的資料庫binlog,從而實現增量數據的回放,結合應用屬性,最後確定採用離線遷移方式,從SqlServer中將表數據全部讀出,然後將數據寫入到pg中,採用此種方案的弊病就是程式端需停止寫入(應用可將部分數據緩存到本地),等待... ...
-
Android 常用 adb 命令總結 adb ( 全稱為Android Debug Bridge)是一個C/S 架構命令行工具,起到調試橋的作用,是連接Android手機與PC端的橋梁,方便我們在電腦上對手機進行操作。adb 命令可用於執行各種設備操作,如安裝和調試應用。 點擊下載adb工具 AD ...
-
支持日語假名註音的JpTextView 支持自動換行 支持自動寬高 支持一次標記或者總是標記 網上找了一下,發現沒有類型的輪子,就自己造了一個 源碼:https://github.com/toukomine/JpTextView 引入依賴 代碼已上傳 mavenCentral倉庫,在項目根目錄的bu ...
-
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 我以前很喜歡封裝組件,什麼東西不喜歡別人的,總喜歡自己搞搞,這讓人很有成就感,雖然是重覆造輪子,但是能從無聊的crud業務中暫時解脫出來,對我來說也算是一種休息,相信有很多人跟我一樣有這個習慣。 這種習慣在獨立開發時無所謂,畢竟沒人 ...
-
react腳手架配置代理總結 方法一 在 package.json 中追加如下配置 "proxy":"<http://localhost:5000>" 說明: 優點:配置簡單,前端請求資源時可以不加任何首碼。 缺點:不能配置多個代理。 工作方式:上述方式配置代理,當請求了3000不存在的資源時,那麼 ...
-
javaScript進階 一、作用域 JS的作用域簡單來說就是變數(變數作用於又稱上下文)和函數生效(能被訪問)的區域 1.全局作用域 函數之外聲明的變數,會成為全局變數。 變數在程式的任何地方都能被訪問,表示它是全局變數,window 對象的內置屬性都擁有全局作用域。 自動全局 如果您為尚未聲明的 ...
-
環境安裝 一、node 1.為什麼需要node環境 Vue.js本質上就是一個Js庫,可以直接在頁面通過script標簽引用。這種使用方式只使用了VueJs的”構建用戶界面“,使用不了他的模塊化 Vue.js可以在html里直接引用後使用,等到與Vue一起配合使用的第三方應用的庫或框架多起來後,一個 ...