export function函數傳參_04 js高階函數(惰性函數、柯里化函數、compose函數)和單例設計模式...

c0acd968ef028051ce3efc96043b4ad0.png

高階函數的定義

在《javascript設計模式和開發實踐》中是這樣定義的。

  • 函數可以作為參數被傳遞;
  • 函數可以作為返回值輸出。

結合這兩個特點,首先想到的肯定是回調函數,回調函數也是高階函數的一種,除了回調函數,還有很多的高階函數,這篇文章主要是惰性函數、柯里化函數、compose函數這三種。

一、惰性函數

概念

懶,執行過一遍的東西,如果第二遍執行還是一樣的效果,則我們就不想讓其重復執行第二遍了

栗子

我們要封裝一個獲取元素屬性的方法,因為低版本的ie瀏覽器不支持getComputedStyle方法,做了一個容錯處理

function getCss(element, attr) {if ('getComputedStyle' in window) {return window.getComputedStyle(element)[attr];}return element.currentStyle[attr];
}

但是每次進這個方法都要做一下判斷,為了提高性能,我們可以存一個變量,然后每次進去判斷變量就好了

var flag = 'getComputedStyle' in window
function getCss(element, attr) {if (flag) {return window.getComputedStyle(element)[attr];}return element.currentStyle[attr];
}

這樣每一次還是需要判斷,有沒有更好的方法呢?惰性函數的思想就可以完美解決這個問題

function getCss(element, attr) {if ('getComputedStyle' in window) {getCss = function (element, attr) {return window.getComputedStyle(element)[attr];};} else {getCss = function (element, attr) {return element.currentStyle[attr];};}// 為了第一次也能拿到值return getCss(element, attr);
}getCss(document.body, 'margin');
getCss(document.body, 'padding');
getCss(document.body, 'width');

第一次執行,如果有getComputedStyle這個方法,getCss就被賦值成

function (element, attr) {return window.getComputedStyle(element)[attr];
};

而后的每一次就會執行上面這個函數,否則則相反

總結

惰性載入函數有兩個主要優點,

  • 1、是顯而易見的效率問題,雖然在第一次執行的時候函數會意味賦值而執行的慢一些,但是后續的調用會因為避免的重復檢測更快;
  • 2、是要執行的適當代碼只有當實際調用函數是才執行,很多JavaScript庫在在加載的時候就根據瀏覽器不同而執行很多分支,把所有東西實現設置好,而惰性載入函數將計算延遲,不影響初始腳本的執行時間。

二、函數柯理化

定義

利用閉包保存機制,把一些信息預先存儲下來(預處理的思想)

function fn() {}
let res = fn(1, 2)(3);
console.log(res); //=>6  1+2+3

封裝一個方法,調用以后求出和(兩次執行的傳參個數都不固定)

解題思路:

函數第二次執行,第一個函數的返回值一定是一個函數,第二個函數的返回值應該是求和的數值function fn(...outerArgs) {return function anonymous(...innerArgs) {// args:外層和里層函數傳遞的所有值都合并在一起let args = outerArgs.concat(innerArgs);return args.reduce((n, item) => n + item);};
}

第二個函數使用了第一個函數的值,所以函數1不會被釋放,利用閉包的保護機制,將值預先保存起來

三、compose函數

定義

組合函數,把多層函數嵌套調用扁平化

栗子

下面四個方法,每種方法都會把參數0進行處理,給x傳一個值如果要得出四種方法以后的和:

const fn1 = (x, y) => x + y + 10;
const fn2 = x => x - 10;
const fn3 = x => x * 10;
const fn4 = x => x / 10;let res = fn4(fn2(fn3(fn1(20))));
let res1 = compose(fn1, fn3, fn2, fn4)(20, 30);

res得出的值,可以實現這個需求,但是需要函數套函數,現在可以定義一個compose函數,使得res和res1的值相等,將函數實現扁平化

function compose(...funcs) {// FUNCS:存儲按照順序執行的函數(數組) =>[fn1, fn3, fn2, fn4]return function anonymous(...args) {// ARGS:存儲第一個函數執行需要傳遞的實參信息(數組)  =>[20]if (funcs.length === 0) return args;if (funcs.length === 1) return funcs[0](...args);return funcs.reduce((N, func) => {// 第一次N的值:第一個函數執行的實參  func是第一個函數// 第二次N的值:上一次func執行的返回值,作為實參傳遞給下一個函數執行return Array.isArray(N) ? func(...N) : func(N);}, args);};
}

完美實現compose函數,不用再函數套函數

react中的redux源碼中的compose函數用的是另外思想實現的

四、單例設計模式

定義

var obj1 = {name: 'wanghuahua'
}
var obj2 = {name: 'jerry'
}
console.log(obj1.name)
console.log(obj2.name)

上面的兩個obj就是最基礎的單例

單例模式就是:用單獨的實例來管理當前事物的相關特征[屬性和方法](類似于實現一個分組的特點)

而此時obj1/obj2不僅僅叫做一個對象,也被成為命名空間

特點

  • 類只有一個實例
  • 全局可訪問該實例
  • 自行實例化(主動實例化)
  • 可推遲初始化,即延遲執行(與靜態類/對象的區別)

雖然全局變量可以實現單例,但因其自身的問題,不建議在實際項目中將其作為單例模式的應用,特別是中大型項目的應用中,全局變量的維護該是考慮的成本。

高級單例設計模式

基于閉包管控的單例模式稱為:高級單例設計模式,以此來實現模塊劃分(最早的模塊化思想)

let wanghuahua = (function () {function query() {}function tools() {}return {name: 'AREA',tools};
})();
wanghuahua.tools();let jerry = (function () {function fn() {meimei.getXxx();}function query() {}return {query}
})();let meimei = (function () {function fn() {}function getXxx() {}jerry.query();return {getXxx}
})(); 
// 每個模塊都可以有自己私有的方法,想要暴露給全局的就return出去// es6的export已經不需要這么寫了公眾號:

ad4a4f47433d8443926ae049361d2998.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396713.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396713.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396713.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Javascript構造函數的繼承

僅供學習參考,原文鏈接:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html 今天要介紹的是,對象之間的"繼承"的五種方法。 比如,現在有一個"動物"對象的構造函數。 funct…

python輸入字符串str_python字符串(str)

#value "raitOrEi"#v value.capitalize()#首字母大寫#print(v)#v1 v.casefold()#全部變小寫,不只是英文的,其他語言特殊的大小寫也變換#print(v1)#v2 v.lower()#只是英文變小寫#print(v2)#設置寬度,并將內容居中#20 代指總長度…

html5 audio api 錄音,如何使用HTML5 Web Audio API錄制我的聲音

在webkit瀏覽器上,您可以將get user media api與webkitGetUserMedia一起使用 – 如html5rocks所示.如果你想用你的聲音來創建javascript事件(例如控制屏幕上的對象)你必須分析傳入的聲音(例如事件1的高頻率 – 事件2的低頻率,語音分析要復雜得多,見下文)另外,還有chrome的’x-w…

修改密碼

在updateservlet.java中寫了方法&#xff0c;修改用戶密碼&#xff0c;代碼不成功求大神指教&#xff0c;代碼如下&#xff1a; updateadminpw.jsp <% page contentType"text/html;charsetgb2312" pageEncoding"gb2312" %><% taglib uri"ht…

MlLib--邏輯回歸筆記

批量梯度下降的邏輯回歸可以參考這篇文章&#xff1a;http://blog.csdn.net/pakko/article/details/37878837 看了一些Scala語法后&#xff0c;打算看看MlLib的機器學習算法的并行化&#xff0c;那就是邏輯回歸&#xff0c;找到package org.apache.spark.mllib.classification下…

mysql相關命令操作

2019獨角獸企業重金招聘Python工程師標準>>> 遠程連接容器中的mysql&#xff1a;mysql -h 192.168.5.116 -P 3306 -u root -p123456 啟動mysql容器&#xff1a; $ sudo docker pull mysql:5.6.35 $ sudo docker run --name mysql -p 12345:3306 -e MYSQL_ROOT_PASSW…

html實體注冊商標,html 注冊商標,html 注冊商標代碼

html中注冊的頁面用什么標簽寫好對于html中的注冊頁面&#xff0c;策朋專業辦理商標注冊、專利申請、版權登記保護&#xff0c;需要一個表格。使用標簽&#xff0c;輸入和按鈕標簽來組合成就。使用html作為注冊頁面。實際上&#xff0c;只要您能達到期望的效果&#xff0c;它的…

java已知一個二叉樹_#二叉樹復習#

#二叉樹復習#目錄滿二叉樹完全二叉樹平衡二叉樹二叉樹的主要性質--二叉樹的度--二叉樹的深度計算二叉樹的遍歷其他符號變量結點總數深度度為0的結點數/葉子結點數度為1的結點數度為2的結點數什么是滿二叉樹&#xff1f;二叉樹每層的結點數為。滿二叉樹總結點數&#xff1a;。圖…

hashtable - hashmap

http://www.importnew.com/24822.html轉載于:https://www.cnblogs.com/qinqiu/p/9711147.html

java 反射機制_基礎篇:深入解析JAVA反射機制

反射的概念java 的放射機制&#xff1a;在程序運行時&#xff0c;程序有能力獲取一個類的所有方法和屬性&#xff1b;并且對于任意一個對象&#xff0c;可以調用它的任意方法或者獲取其屬性通俗解析&#xff1a;java 文件需要編譯成. class 文件才能被 jvm 加載使用, 對象的. c…

構建之法閱讀筆記01

本學期閱讀計劃有兩個&#xff0c;一個是《構建之法》&#xff0c;另一個是《大道至簡》。 在快速閱讀構建之法后&#xff0c;我想提一下幾個問題&#xff1a; 1、軟件程序軟件工程&#xff0c;那么只會軟件工程是怎樣具體詳細的將程序變成合格的軟件的&#xff1f; 2、效能分析…

html div float center,跨瀏覽器實現float:center

跨瀏覽器實現float:center互聯網 發布時間&#xff1a;2008-10-17 19:26:11 作者&#xff1a;佚名 我要評論原文&#xff1a;http://www.macji.com/blog/article/to-achieve-cross-browser-css-float-center/to-achieve-cross-browser-css-float-center/我們都知道float…

博弈論中:納什均衡、純策略納什均衡、混合策略納什均衡、占優策略

納什均衡 納什均衡是由約翰福布斯納什&#xff08;John Forbes Nash&#xff09;在20世紀50年代提出的博弈論概念&#xff0c;用于描述博弈中的一種穩定狀態。在納什均衡狀態下&#xff0c;每個參與者都假定其他參與者的策略是已知的&#xff0c;他們選擇的策略是最優的&#…

工具_HBuilder使用快捷方式

HBuilder常用快捷鍵大概共9類&#xff08;【4 13 3】文件、編輯、插入&#xff1b;【4 9 8】選擇、跳轉、查找&#xff1b;【1 1 6】運行、工具、視圖&#xff09; 1.文件(4) 新建 Ctrl N 關閉 Ctrl F4 全部關閉 Ctrl Shift F4 屬性 Alt Enter 2.編輯(13) 激活代碼助…

oracle左連接沒用_一周零基礎學完Oracle數據庫第三天02

四、 多表查詢1 什么是多表查詢多表查詢&#xff1a;當查詢的數據并不是來源一個表時&#xff0c;需要使用多表鏈接操作完成查詢。根據 不同表中的數據之間的關系查詢相關聯的數據。多表鏈接方式&#xff1a; 內連接&#xff1a;連接兩個表&#xff0c;通過相等或不等判斷鏈接列…

weblogic啟動項目報錯找不到類_啟動類報錯是經常出現的事但是單一的從一個地方找原因會越找越錯...

Error starting ApplicationContext. To display the conditions report rerun your application with debug enabled.當我們看到這個報錯的時候有的說是jar包重復&#xff0c;有的說是Controller包和Application包處于平行位置&#xff0c;還有的覺得是RequestMapping的valu…

fis

fis3實時刷新 npm install -g fis3 進入相關目錄 發布&#xff1a; fis3 release 啟動&#xff1a; fis3 server start // 服務啟動后&#xff0c;會一直存在&#xff0c;重啟或者fis3 server stop 才會關閉服務 自動刷新 fis3 release -wL關閉服務 fis3 server stop …

深入理解javascript原型和閉包(7)——原型的靈活性

在Java和C#中&#xff0c;你可以簡單的理解class是一個模子&#xff0c;對象就是被這個模子壓出來的一批一批月餅&#xff08;中秋節剛過完&#xff09;。壓個啥樣&#xff0c;就得是個啥樣&#xff0c;不能隨便動&#xff0c;動一動就壞了。 而在javascript中&#xff0c;就沒…

微型計算機一般不采用的控制方式,微型計算機控制作業.doc

作業一PID控制器引言在實際的過程控制與運動控制系統中&#xff0c;PID家族占據有相當的地位&#xff0c;據統計&#xff0c;工業控制的控制器中PID類控制占有90%以上。PID控制器是最早出現的控制器類型&#xff0c;因為其結構簡單&#xff0c;各個控制器參數有著明顯的物理意義…

js根據毫米/厘米算像素px

<html><meta http-equiv"content-type" content"text/html;charsetutf-8"><body> 紙張寬度(毫米mm)&#xff1a;<input type"text" id"width" value"10"> <span id"width_px"><…