js 函數(shù)的副作用分析
更新時(shí)間:2011年08月23日 22:54:54 作者:
函數(shù)副作用 指當(dāng)調(diào)用函數(shù)時(shí),除了返回函數(shù)值之外,還對主調(diào)用函數(shù)產(chǎn)生附加的影響。例如修改全局變量(函數(shù)外的變量)或修改參數(shù)。
函數(shù)副作用會給程序設(shè)計(jì)帶來不必要的麻煩,給程序帶來十分難以查找的錯誤,并且降低程序的可讀性。嚴(yán)格的函數(shù)式語言要求函數(shù)必須無副作用。
函數(shù)的副作用相關(guān)的幾個概念, Pure Function、 Impure Function、 Referential Transparent。
純函數(shù) ( Pure Function )
輸入輸出數(shù)據(jù)流全是顯式(Explicit)的。 顯式(Explicit)的意思是,函數(shù)與外界交換數(shù)據(jù)只有一個唯一渠道——參數(shù)和返回值。函數(shù)從函數(shù)外部接受的所有輸入信息都通過參數(shù)傳遞到該函數(shù)內(nèi)部。函數(shù)輸出到函數(shù)外部的所有信息都通過返回值傳遞到該函數(shù)外部。
非純函數(shù) ( Impure Function )
與之相反。 隱式(Implicit)的意思是,函數(shù)通過參數(shù)和返回值以外的渠道,和外界進(jìn)行數(shù)據(jù)交換。比如讀取/修改全局變量,都叫作以隱式的方式和外界進(jìn)行數(shù)據(jù)交換。
引用透明 ( Referential Transparent )
引用透明的概念與函數(shù)的副作用相關(guān),且受其影響。 如果程序中兩個相同值得表達(dá)式能在該程序的任何地方互相替換,而不影響程序的動作,那么該程序就具有引用透明性。它的優(yōu)點(diǎn)是比非引用透明的語言的語義更容易理解,不那么晦澀。純函數(shù)式語言沒有變量,所以它們都具有引用透明性。
以下示例說明了引用透明與函數(shù)副作用的結(jié)合
result1 = (fun(a) + b) / (fun(a) -c);
temp = fun(a);
result2 = (temp + b) / (temp -c);
如果函數(shù)沒有副作用,那么result1和result2將是等價(jià)的。然而如果fun有副作用,比如讓b或c加1,那么result1和result2將不相等。因此,副作用違背了引用透明性。
在JavaScript中,引入了函數(shù)。但顯然JS中的函數(shù)可以訪問、修改全局變量(或定義在函數(shù)外的變量),如下
var a = 5;
function fun(){
a = 10;
}
fun(); // a 變成了10
JS中要想保證函數(shù)無副作用這項(xiàng)特性,只能依靠編程人員的習(xí)慣,即
1,函數(shù)入口使用參數(shù)運(yùn)算,而不修改它
2,函數(shù)內(nèi)不修改函數(shù)外的變量,如全局變量
3,運(yùn)算結(jié)果通過函數(shù)返回給外部(出口)
函數(shù)的副作用相關(guān)的幾個概念, Pure Function、 Impure Function、 Referential Transparent。
純函數(shù) ( Pure Function )
輸入輸出數(shù)據(jù)流全是顯式(Explicit)的。 顯式(Explicit)的意思是,函數(shù)與外界交換數(shù)據(jù)只有一個唯一渠道——參數(shù)和返回值。函數(shù)從函數(shù)外部接受的所有輸入信息都通過參數(shù)傳遞到該函數(shù)內(nèi)部。函數(shù)輸出到函數(shù)外部的所有信息都通過返回值傳遞到該函數(shù)外部。
非純函數(shù) ( Impure Function )
與之相反。 隱式(Implicit)的意思是,函數(shù)通過參數(shù)和返回值以外的渠道,和外界進(jìn)行數(shù)據(jù)交換。比如讀取/修改全局變量,都叫作以隱式的方式和外界進(jìn)行數(shù)據(jù)交換。
引用透明 ( Referential Transparent )
引用透明的概念與函數(shù)的副作用相關(guān),且受其影響。 如果程序中兩個相同值得表達(dá)式能在該程序的任何地方互相替換,而不影響程序的動作,那么該程序就具有引用透明性。它的優(yōu)點(diǎn)是比非引用透明的語言的語義更容易理解,不那么晦澀。純函數(shù)式語言沒有變量,所以它們都具有引用透明性。
以下示例說明了引用透明與函數(shù)副作用的結(jié)合
復(fù)制代碼 代碼如下:
result1 = (fun(a) + b) / (fun(a) -c);
temp = fun(a);
result2 = (temp + b) / (temp -c);
如果函數(shù)沒有副作用,那么result1和result2將是等價(jià)的。然而如果fun有副作用,比如讓b或c加1,那么result1和result2將不相等。因此,副作用違背了引用透明性。
在JavaScript中,引入了函數(shù)。但顯然JS中的函數(shù)可以訪問、修改全局變量(或定義在函數(shù)外的變量),如下
復(fù)制代碼 代碼如下:
var a = 5;
function fun(){
a = 10;
}
fun(); // a 變成了10
JS中要想保證函數(shù)無副作用這項(xiàng)特性,只能依靠編程人員的習(xí)慣,即
1,函數(shù)入口使用參數(shù)運(yùn)算,而不修改它
2,函數(shù)內(nèi)不修改函數(shù)外的變量,如全局變量
3,運(yùn)算結(jié)果通過函數(shù)返回給外部(出口)
相關(guān)文章
如何使用JS獲取當(dāng)前節(jié)點(diǎn)的兄弟/父/子節(jié)點(diǎn)
在日常的網(wǎng)頁開發(fā)中,我們會遇到獲取節(jié)點(diǎn)的問題,而js是寫網(wǎng)頁的最基礎(chǔ)的語言,也是最常用的,這篇文章主要給大家介紹了關(guān)于如何使用JS獲取當(dāng)前節(jié)點(diǎn)的兄弟/父/子節(jié)點(diǎn)的相關(guān)資料,需要的朋友可以參考下2023-04-04
Java中int與integer的區(qū)別(基本數(shù)據(jù)類型與引用數(shù)據(jù)類型)
這篇文章主要介紹了int與integer的區(qū)別(基本數(shù)據(jù)類型與引用數(shù)據(jù)類型),簡單的說 int 是基本數(shù)據(jù)類型,integer 是引用數(shù)據(jù)類型,具體區(qū)別詳解大家參考下本文2017-02-02
JavaScript 序列化對象實(shí)現(xiàn)代碼
JavaScript序列化對象實(shí)現(xiàn)代碼,需要的朋友可以參考下。2009-12-12
javascript數(shù)組克隆簡單實(shí)現(xiàn)方法
這篇文章主要介紹了javascript數(shù)組克隆簡單實(shí)現(xiàn)方法,實(shí)例分析了JavaScript中concat用于數(shù)組克隆的使用技巧,需要的朋友可以參考下2015-12-12
js實(shí)現(xiàn)動態(tài)改變r(jià)adio狀態(tài)的方法
下面小編就為大家分享一篇js實(shí)現(xiàn)動態(tài)改變r(jià)adio狀態(tài)的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02

