本文是函數式程式設計系列的第一篇文章。這裡我會簡單介紹一下程式設計範式,然後會直接介紹使用 Javascript 進行函數式程式設計的概念,因為 JavsScript 是最被認可的函數式程式語言之一。我們鼓勵讀者透過參考資料部分進一步了解這個迷人的概念。
程式設計範式
程式設計範式是一個由思考問題以及實現問題願景的工具所組成的框架。很多現代語言都是聚範式(或多重範式): 他們支援很多不同的程式範式,像是物件導向,元程式設計,泛函,面向過程,等等。
函數式程式設計範式
函數式程式設計就像是氫燃料驅動的汽車-先進的未來派,但還沒有被廣泛推廣。與命令式程式設計相反,他由一系列語句組成,這些語句用於更新執行時的全域狀態。函數式程式設計將計算轉換作表達式求值。這些表達式全由純數學函數組成,這些函數都是一流的(可以被當做一般值來運用和處理),並且沒有副作用。
函數式程式設計很重視以下值:
函數是一等要務
我們應該將函數與程式語言中的其他類別物件同樣對待。換句話說,您可以將函數儲存在變數裡,動態建立函數,以及將函數傳回或將函數傳遞給其他函數。下面我們來看一個例子…
一個字串可以儲存為一個變量,函數也可以,例如:
var sayHello = function() { return “Hello” };
一個字串可以儲存為物件字段,函數也可以,例如:
var person = {message: “Hello”, sayHello: function() { return “Hello” }};
一個字串可以再用到時才創建,函數也可以,例如:
“Hello ” + (function() { return “World” })(); //=> Hello World
一個字串可以作為輸入參數傳給函數,則函數也可以:
function hellloWorld(hello, world) { return hello + world() }
一個字串可以作為函數傳回值,函數也可以,例如:
return “Hello”; return function() { return “Hello”};
高階案例
如果函數將其他函數函數作為輸入參數或作為傳回值,則稱之為高階函數。剛才我們已經看過了一個高階函數的例子。下面,我們來看看更複雜的情況。
範例1:
[1, 2, 3].forEach(alert); // alert 弹窗显示“1" // alert 弹窗显示 "2" // alert 弹窗显示 "3”
範例2:
function splat(fun) { return function(array) { return fun.apply(null, array); }; } var addArrayElements = splat(function(x, y) { return x + y }); addArrayElements([1, 2]); //=> 3
最愛純函數
純函數不會有其他的副作用,所謂的副作用指的是函數所產生的函數外界狀態的修改。例如:
修改某個變數
修改資料結構
對外界某個變數設定欄位
拋出例外或彈出錯誤訊息
#最簡單的範例就是數學函數。 Math.sqrt(4) 函數總是傳回2。他不會用到任何其他心寒訊息,如狀態或設定參數。數學函數從來不會造成任何副作用。
避免修改狀態
函數式程式設計支持純粹的函數,這樣的函數不能改變數據,因此大多用於創建不可改變的數據。這種方式,不用修改一個已存在的資料結構,而且能高效的新建一個.
你也許想知道,如果一個純粹的函數通過改變一些本地數據而生產一個不可改變的返回值,是否是允許的?答案是可以。
在JavaScript中極少的資料型別是預設是不可改變的。 String是一個不能改變的資料類型的例子:
var s = "HelloWorld"; s.toUpperCase(); //=> "HELLOWORLD" s; //=> "HelloWorld"
不可改變狀態的好處
• 避免混亂和增加程式的準確性:在複雜系統內,大多數難以理解的Bug是由於狀態透過在程式中外部客戶端程式碼修改而導致的。
• 確立「快速簡潔」的多執行緒程式設計:如果多執行緒可以修改同一個共享值,你不得不同步的取得值。這對專家來說都是十分乏味且易出錯的程式設計挑戰。
軟體事務記憶體和Actor模型提供了直接在線程安全方式下處理修改。
使用遞迴而非循環呼叫
递归是最有名的函数式编程技术。如果您还不知道它的话,那么可以理解为递归函数就是一个可以调用自己的函数。
替代反复循环的最经典方式就是使用递归,即每次完成函数体操作之后,再继续执行集合里的下一项,直到满足结束条件。递归还天生符合某些算法实现,比如遍历树形结构(每个树枝都是一颗小树)。
在任何语言里,递归都是一项重要的函数式编程方式。很多函数语言甚至要求的更加严格:只支持递归遍历,而不支持显式的循环遍历。这需要语言必须保证消除了尾端调用,这是 JavasSrip 不支持的。
惰性求值优于激进计算
数学定义了很多无穷集合,比如自然数(所有的正整数)。他们都是符号表示。任意特定有限的子集都在需要时求值。我们将其称之为惰性求值(也叫做非严格求值,或者按需调用,延迟执行)。及早求值会强迫我们表示出所有无穷数据,而这显然是不可能的。
很多语言都默认是惰性的,有些也提供了惰性数据结构以表达无穷集合,并在需要时对自己进行精确计算。
很明显一行代码 result = compute() 所表达的是将 compute() 的返回结果赋值给 result。但是 result 的值究竟是多少只有其被用到的时候才有意义。
可见策略的选择会在很大程度上提高性能,特别是当用在链式处理或者数组处理的时候。这些都是函数式程序员所喜爱的编程技术。
这就开创可很多可能性,包括并发执行,并行技术以及合成。
但是,有一个问题,JavaScrip 并不对自身进行惰性求值。话虽如此,Javascript 里的函数库可以有效地模拟惰性求值。
闭包的全部好处
所有的函数式语言都有闭包,然而这个语言特性经常被讨论得很神秘。闭包是一个函数,这个函数有着对内部引用的所有变量的隐式绑定。换句话说,该函数对它引用的变量封闭了一个上下文。JavaScript 中的闭包是能够访问父级作用域的函数,即使父级函数已经调用完毕。
function multiplier(factor) { return function(number) { return number * factor; }; } var twiceOf = multiplier(2); console.log(twiceOf(6)); //=> 12
声明式优于命令式编程
函数式编程是声明式的,就像数学运算,属性和关系是定义好的。运行时知道怎么计算最终结果。阶乘函数的定义提供了一个例子:
factorial(n) = 1 if n = 1
n * factorial(n-1) if n > 1
该定义将 factorial(n) 的值关联到 factorial(n-1),是递归定义。特殊情况下的 factorial(1) 终止了递归。
var imperativeFactorial = function(n) { if(n == 1) { return 1 } else { product = 1; for(i = 1; i <= n; i++) { product *= i; } return product; } } var declarativeFactorial = function(n) { if(n == 1) { return 1 } else { return n * factorial(n - 1); } }
从它实现阶乘计算来看,声明式的阶乘可能看起来像“命令式”的,但它的结构更像声明式的。
命令式阶乘使用可变值、循环计数器和结果来累加计算后的结果。这个方法显式地实现了特定的算法。不像声明式版本,这种方法有许多可变步骤,导致它更难理解,也更难避免 bug 。
函数式JavaScript库
有很多函数式库:underscore.js, lodash,Fantasy Land, Functional.js, Bilby.js, fn.js, Wu.js, Lazy.js, Bacon.js, sloth.js, stream.js, Sugar, Folktale, RxJs 等等。
函数式程序员工具包
map(), filter(), 和 reduce()函数 构成了函数式程序员工具包的核心。 纯高阶函数成了函数式方法的主力。事实上,它们是纯函数和高阶函数应该仿效的典型。它们用一个函数作为输入,返回没有副作用的输出。
以上是詳細介紹使用JavaScript進行函數式程式設計 (一)(圖)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Dreamweaver CS6
視覺化網頁開發工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。