8個JavaScript中高階函數(shù)的運用分享
函數(shù)作為參數(shù)傳遞
高階函數(shù)可以接受一個或多個函數(shù)作為參數(shù),這些函數(shù)可以在高階函數(shù)中被調(diào)用,實現(xiàn)某種特定的功能
function operation(num1, num2, callback) {
let result = callback(num1, num2);
console.log(result);
}
function add(num1, num2) {
return num1 + num2;
}
operation(2, 3, add); // 輸出 5
在上面的例子中,operation 函數(shù)接受三個參數(shù),其中第三個參數(shù)是一個回調(diào)函數(shù) callback,它的作用是對前兩個參數(shù)進(jìn)行某種操作,返回操作結(jié)果。在調(diào)用 operation 函數(shù)時,我們將 add 函數(shù)作為 callback 參數(shù)傳入,從而實現(xiàn)了兩個數(shù)的加法運算
函數(shù)作為返回值
高階函數(shù)可以返回一個或多個函數(shù),這些函數(shù)可以在其他地方調(diào)用,實現(xiàn)某種特定的功能
function multiplyBy(num) {
return function(x) {
return x * num;
}
}
let multiplyBy2 = multiplyBy(2);
console.log(multiplyBy2(5)); // 輸出 10
在上面的例子中,multiplyBy 函數(shù)返回了一個匿名函數(shù),該函數(shù)接受一個參數(shù) x,并將其乘以 num 參數(shù)。我們將 multiplyBy(2) 賦值給 multiplyBy2 變量,從而得到一個新的函數(shù),該函數(shù)可以將其參數(shù)乘以 2。最后,我們調(diào)用 multiplyBy2(5) ,得到 10
函數(shù)柯里化
柯里化是一個將多個參數(shù)的函數(shù)轉(zhuǎn)換為一系列單參數(shù)函數(shù)的過程。這種方式可以更方便地傳遞參數(shù),提高代碼的可讀性和可維護(hù)性
function add(num1) {
return function(num2) {
return num1 + num2;
}
}
let add5 = add(5);
console.log(add5(3)); // 輸出 8
在上面的例子中,add 函數(shù)接受一個參數(shù) num1,并返回一個匿名函數(shù),該函數(shù)接受一個參數(shù) num2,并將其與 num1 相加。我們將 add(5) 賦值給 add5 變量,從而得到一個新的函數(shù),該函數(shù)可以將其參數(shù)與 5 相加。最后,我們調(diào)用 add5(3) ,得到 8
函數(shù)組合
函數(shù)組合是將多個函數(shù)組合成一個新函數(shù)的過程。這種方式可以將多個操作封裝在一起,減少代碼的冗余和重復(fù)
function add(num) {
return num + 1;
}
function multiplyBy2(num) {
return num * 2;
}
function compose(f, g) {
return function(x) {
return f(g(x));
}
}
let addThenMultiply = compose(multiplyBy2, add);
console.log(addThenMultiply(2)); // 輸出 6
在上面的例子中,我們定義了三個函數(shù) add、multiplyBy2 和 compose。add 和 multiplyBy2 分別實現(xiàn)了加 1 和乘以 2 的操作,compose 函數(shù)接受兩個函數(shù)作為參數(shù),并返回一個新的函數(shù),該函數(shù)可以將這兩個函數(shù)組合在一起。我們將 multiplyBy2 和 add 作為參數(shù)傳給 compose,得到一個新的函數(shù) addThenMultiply,該函數(shù)先將其參數(shù)加 1,然后再將結(jié)果乘以 2。最后,我們調(diào)用 addThenMultiply(2) ,得到 6
面向切面編程
面向切面編程是一種將橫切關(guān)注點與業(yè)務(wù)邏輯分離的編程方式。這種方式可以提高代碼的可維護(hù)性和可擴(kuò)展性
function logExecutionTime(fn) {
return function() {
console.time('Execution time');
let result = fn.apply(null, arguments);
console.timeEnd('Execution time');
return result;
}
}
function add(num1, num2) {
return num1 + num2;
}
let timedAdd = logExecutionTime(add);
console.log(timedAdd(2, 3)); // 輸出 Execution time: 0.048ms 5
在上面的例子中,我們定義了兩個函數(shù) logExecutionTime 和 add。logExecutionTime 函數(shù)接受一個函數(shù)作為參數(shù),并返回一個新的函數(shù),該函數(shù)會在執(zhí)行原函數(shù)時記錄其執(zhí)行時間。我們將 add 函數(shù)作為參數(shù)傳給 logExecutionTime,得到一個新的函數(shù) timedAdd,該函數(shù)在執(zhí)行加法操作時會記錄其執(zhí)行時間。最后,我們調(diào)用 timedAdd(2, 3) ,得到 5,并在控制臺輸出執(zhí)行時間
函數(shù)式編程
函數(shù)式編程是一種將計算過程看作是函數(shù)之間的組合的編程方式。這種方式可以提高代碼的可讀性和可維護(hù)性,減少副作用和狀態(tài)變量的使用
let numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce(function(acc, num) {
return acc + num;
}, 0);
console.log(sum); // 輸出 15
在上面的例子中,我們使用了 JavaScript 內(nèi)置的 reduce 函數(shù),實現(xiàn)了對數(shù)組中所有數(shù)字的求和。reduce 函數(shù)接受兩個參數(shù):一個回調(diào)函數(shù)和一個初始值?;卣{(diào)函數(shù)接受兩個參數(shù):累加器和當(dāng)前元素,返回值會被作為下一次調(diào)用回調(diào)函數(shù)時的累加器參數(shù)。在這個例子中,我們使用匿名函數(shù)作為回調(diào)函數(shù),實現(xiàn)了將累加器和當(dāng)前元素相加的操作。最后,我們將初始值設(shè)為 0,得到了數(shù)組中所有數(shù)字的和
閉包
閉包是指一個函數(shù)可以訪問其定義時的作用域中的變量和參數(shù)。這種方式可以實現(xiàn)局部變量的封裝和保護(hù),提高代碼的安全性和穩(wěn)定性
在上面的例子中,我們使用了閉包來實現(xiàn)函數(shù)柯里化和函數(shù)作為返回值。具體來說,我們定義了一個函數(shù) add,它接受一個參數(shù) num1,并返回一個匿名函數(shù),該函數(shù)接受一個參數(shù) num2,并將其與 num1 相加。這樣,我們就可以將 add(5) 賦值給變量 add5,得到一個新的函數(shù),該函數(shù)可以將其參數(shù)與 5 相加
閉包的使用場景包括:
- 封裝變量:閉包可以將變量封裝在函數(shù)內(nèi)部,避免全局變量的污染和沖突。
- 保護(hù)變量:閉包可以將變量保護(hù)起來,避免其被外部訪問和修改,提高代碼的安全性和穩(wěn)定性。
- 實現(xiàn)模塊化:閉包可以將一組相關(guān)的函數(shù)和變量封裝在一個函數(shù)內(nèi)部,形成一個模塊,提高代碼的可維護(hù)性和可擴(kuò)展性。
- 實現(xiàn)柯里化和函數(shù)組合:閉包可以將函數(shù)柯里化和函數(shù)組合的實現(xiàn)變得更加簡單和直觀。
- 實現(xiàn)面向?qū)ο缶幊蹋洪]包可以將函數(shù)作為對象的方法,實現(xiàn)面向?qū)ο缶幊痰姆绞健?/li>
總之,閉包是 JavaScript 中非常重要的概念,它可以幫助我們更好地組織代碼,提高代碼的可讀性、可維護(hù)性和可擴(kuò)展性。但是,過度使用閉包也可能會導(dǎo)致代碼的復(fù)雜性和性能問題,因此需要謹(jǐn)慎使用。
復(fù)雜的例子
以下是一個更復(fù)雜的例子,它結(jié)合了多個高階函數(shù)的概念,包括函數(shù)作為參數(shù)傳遞、函數(shù)作為返回值、函數(shù)柯里化、函數(shù)組合和面向切面編程
// 定義一個數(shù)組,包含一些數(shù)字
let numbers = [1, 2, 3, 4, 5];
// 定義一個函數(shù),用于將數(shù)組中的每個元素加上一個指定的值
function add(amount) {
return function(num) {
return num + amount;
}
}
// 定義一個函數(shù),用于將數(shù)組中的每個元素乘以一個指定的值
function multiplyBy(factor) {
return function(num) {
return num * factor;
}
}
// 定義一個函數(shù),用于將數(shù)組中的所有元素相加
function sum(numbers) {
return numbers.reduce(function(acc, num) {
return acc + num;
}, 0);
}
// 定義一個函數(shù),用于記錄函數(shù)執(zhí)行時間
function logExecutionTime(fn) {
return function() {
console.time('Execution time');
let result = fn.apply(null, arguments);
console.timeEnd('Execution time');
return result;
}
}
// 定義一個函數(shù),用于組合多個函數(shù)
function compose() {
let fns = Array.prototype.slice.call(arguments); // 將參數(shù)轉(zhuǎn)換為數(shù)組
return function(x) {
return fns.reduceRight(function(acc, fn) {
return fn(acc);
}, x);
}
}
// 將數(shù)組中的每個元素加上 1,再將結(jié)果乘以 2,最后計算所有元素的和
let result = compose(logExecutionTime(sum), multiplyBy(2), add(1))(numbers);
console.log(result); // 輸出 Execution time: 0.131ms 30
詳細(xì)解釋:
- 在上面的例子中,我們首先定義了一個包含一些數(shù)字的數(shù)組 numbers。然后,我們定義了三個函數(shù) add、multiplyBy 和 sum。add 和 multiplyBy 分別返回一個匿名函數(shù),該函數(shù)接受一個數(shù)字參數(shù),并將其加上或乘以另一個數(shù)字。sum 函數(shù)使用 JavaScript 內(nèi)置的 reduce 函數(shù),計算數(shù)組中所有數(shù)字的和
- 接下來,我們定義了一個函數(shù) logExecutionTime,用于記錄函數(shù)執(zhí)行時間。該函數(shù)接受一個函數(shù)作為參數(shù),并返回一個新的函數(shù),該函數(shù)在執(zhí)行原函數(shù)時記錄其執(zhí)行時間
- 然后,我們定義了一個函數(shù) compose,用于組合多個函數(shù)。該函數(shù)接受任意數(shù)量的函數(shù)作為參數(shù),并返回一個新的函數(shù),該函數(shù)可以將這些函數(shù)組合在一起,并按照從右到左的順序依次調(diào)用它們。在 compose 函數(shù)內(nèi)部,我們使用了 Array.prototype.slice.call(arguments) 將參數(shù)列表轉(zhuǎn)換為數(shù)組,并使用 reduceRight 函數(shù)依次調(diào)用這些函數(shù)
- 最后,我們使用函數(shù)柯里化和函數(shù)組合,將 logExecutionTime、sum、multiplyBy 和 add 函數(shù)組合在一起,實現(xiàn)了將數(shù)組中的每個元素加上 1,再將結(jié)果乘以 2,最后計算所有元素的和。我們將 numbers 數(shù)組作為參數(shù)傳給該函數(shù),得到了最終的結(jié)果,并在控制臺輸出了執(zhí)行時間
以上就是8個JavaScript的高階函數(shù)的運用分享的詳細(xì)內(nèi)容,更多關(guān)于JavaScript高階函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript面試必備之垃圾回收機(jī)制和內(nèi)存泄漏詳解
垃圾回收機(jī)制和內(nèi)存泄漏是JavaScript面試時常常問到的問題,這篇文章就為大家詳細(xì)整理了他們的相關(guān)知識,感興趣的小伙伴可以跟隨小編一起了解一下2023-05-05
Javascript 異步加載詳解(瀏覽器在javascript的加載方式)
本文總結(jié)一下瀏覽器在 javascript 的加載方式,需要的朋友可以參考下2012-05-05
js使用html2canvas實現(xiàn)屏幕截取的示例代碼
這篇文章主要介紹了js使用html2canvas實現(xiàn)屏幕截取的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08
深入淺出ES6新特性之函數(shù)默認(rèn)參數(shù)和箭頭函數(shù)
這篇文章主要介紹了深入淺出ES6新特性之函數(shù)默認(rèn)參數(shù)和箭頭函數(shù) 的相關(guān)資料,需要的朋友可以參考下2016-08-08

