提高你的javascript代碼逼格系列之函數與數組

不知道大家有沒有一種感覺,那就是自己寫的javascript代碼雖然能完全解決工作上的需要,但是,一眼望去,too simple!!!簡直就是一個傻子都能看懂的水平,于是,在工作之余,我開始去收集一些幾乎在日常開發中未曾用過的javascript寫法/有價值的javascript知識點,借此來提高自身javascript水平。

一、函數式編程與面向對象編程

<script>/*函數式編程*/function f1(){var n=999;nAdd=function(){n+=1;};var f2 = function(){console.log(n);};return f2;}var result=f1();result(); // 999
  nAdd();result(); // 1000/*面向對象編程1之json寫法*/var obj1 = {n:999,nAdd:function(){this.n += 1;},getN:function(){console.log(this.n);}};obj1.getN();//999
    obj1.nAdd();obj1.getN();//1000/*面向對象編程2之工廠模式*/var obj2 = function(){var obj = new Object;obj.n = 999;obj.nAdd = function(){this.n += 1;};obj.getN = function(){console.log(this.n);}return obj;};var objins = new obj2();objins.getN();//999
    objins.nAdd();objins.getN();//1000/*面向對象編程3之原型prototype*/function obj3(n) {this.n = n;}obj3.prototype.nAdd = function() {this.n+=1;};obj3.prototype.getN = function() {console.log(this.n);}var objins2 = new obj3(999);objins2.getN();//999
    objins2.nAdd();objins2.getN();//1000
</script>
View Code

針對上面所示的函數式編程,涉及了作用域和閉包的知識,這里簡要提一下;

里面的nAdd沒有用var關鍵字聲明,所以他是全局的,后面可以全局調用,其次利用閉包訪問和修改了函數作用域內的n值。

二、純函數和非純函數

1.此函數在相同的輸入值時,總是產生相同的輸出。函數的輸出和當前運行環境的上下文狀態無關。

2.此函數運行過程不影響運行環境,也就是無副作用(如觸發事件、發起http請求、打印/log等)。

簡單來說,也就是當一個函數的輸出不受外部環境影響,同時也不影響外部環境時,該函數就是純函數,也就是它只關注邏輯運算和數學運算,同一個輸入總得到同一個輸出。

var xs = [1,2,3,4,5];
// 純的
xs.slice(0,3);
//=> [1,2,3]
xs.slice(0,3);
//=> [1,2,3]
xs.slice(0,3);
//=> [1,2,3]// 不純的
xs.splice(0,3);
//=> [1,2,3]
xs.splice(0,3);
//=> [4,5]
xs.splice(0,3);
//=> []
View Code

純函數相對于非純函數來說,在可緩存性、可移植性、可測試性以及并行計算方面都有著巨大的優勢。

三、函數的柯里化

curry 的概念很簡單:將一個低階函數轉換為高階函數的過程就叫柯里化。

函數柯里化是一種“預加載”函數的能力,通過傳遞一到兩個參數調用函數,就能得到一個記住了這些參數的新函數。從某種意義上來講,這是一種對參數的緩存,是一種非常高效的編寫函數的方法:

                /*一般寫法:兩數相加*/var add = function(x,y){return x + y;}/*2+1和2+10*/add(2,1);//3add(2,10);//12/*柯里化寫法*///es5var add = function(x) {return function(y) {return x + y;};};//es6var add = x => (y => x + y);//定義+1和+10函數var increment = add(1);//柯里化后得到的+1函數var addTen = add(10);//柯里化后得到的+10函數increment(2);  // 3addTen(2);  // 12
View Code

四、Array.reduce/Array.reduceRight(數組迭代)

先不看標題,來個題目:如何求數組[1,2,3,4,5]的各項累加的和?

大多數人恐怕會立即說出for循環、while循環,的確,for循環和while循環是可以解決上述問題,但是,這個答案顯然脫離了此篇博客的主題:逼格!!!

并且,實驗表明,將上述求和方法循環1W次,用for循環和while循環耗時大概在50~55ms,但是,用Array.reduce/Array.reduceRight僅僅耗時0.4ms!!!

關于該方法的詳解,請猛戳→https://www.w3cplus.com/javascript/array-part-8.html;這里給個demo:

var arr = [1,2,3,4,5];/*ES6寫法*/var reducer = (prevalue,curvalue)=>prevalue + curvalue;console.log(arr.reduce(reducer));//15/*ES5寫法*/var reducer = function(prevalue,curvalue){return prevalue + curvalue;};console.log(arr.reduce(reducer));//15/*解析*/數組的reduce方法有兩個參數:callback,prevalue;對于第一個參數callback,里面有4個參數prevalue、curvalue、index、array;index是當前迭代時的curvalue的索引(數組中的索引),array當然是操作的數組了;著重看另外兩個參數,prevalue和curvalue(上一個值和當前值);如果reduce方法沒有第二個參數的話,那么callback回調將數組第一個值作為prevalue,第二個值作為curvalue;如果reduce方法有第二個參數,那么將第二個參數值作為prevalue,將數組第一個值作為curvalue;每一次的操作結果將變為下一次操作的prevalue,而curvalue的值教上一次往后推一位;/*實例解析*/針對上述數組相加;沒有第二個參數,只有一個回調callback,那么他的過程是這樣的;第一次運算:prevalue為1,curvalue為2,運算結果為1+2=3,并將結果作為下次運算的prevalue;第二次運算:prevalue為3(上一次運算的結果),curvalue為3,運算結果為3+3=4,以此類推;如果有第二個參數,假設為5,arr.reduce(reducer,5),那么將是這么計算的;第一次運算:prevalue為5(第二個參數),curvalue為1,運算結果為5+1=6,并將結果作為下次運算的prevalue;第二次運算:prevalue為6(上一次運算的結果),curvalue為2,運算結果為6+2=8,以此類推;reduceRight和reduce類似,只不過他是從右邊開始迭代的。
View Code

?五、函數組合(reduce高級用法)

假想一下,要將字符串“my name is echo”進行如下操作,你會怎么做?轉大寫、然后末尾加一個感嘆號;

我想你大概會定義一個函數operate,對于形參str,先toUpperCase(),然后+ '!',ok這樣做沒錯,但是現在我需求改了,我不要求轉大寫了,你是不是得刪除那行代碼?

可能你會說了,我定義兩個函數一個是轉大寫,一個是加嘆號,需要哪個用哪個,其實無論你用幾個函數來寫,還是直接用prototype或者鏈式調用的方法去寫,都只是大眾化的寫法,且不易維護,so,請看下面的寫法:

        var compose = (...args) => x => args.reduceRight((prevalue, curvalue) => curvalue(prevalue), x);var toUpperCase = x => x.toUpperCase();var exclaim = x => x + '!';var shout = compose(exclaim, toUpperCase);console.log(shout("my name is echo"));
View Code

?一眼望去,是不是兩眼懵逼?!!不怕,我們用ES5還原一下,請看:

        var compose = function (...args){return function (x){return args.reduceRight(function(prevalue, curvalue){return curvalue(prevalue);},x)}};var toUpperCase = function(x){return x.toUpperCase();};var exclaim = function(x){return x + '!';};var shout = compose(exclaim, toUpperCase);console.log(shout("my name is echo"));
View Code

結合上述第四例所講到的reduce,我希望此時你已經看懂了,沒看懂也沒關系,接著往下看,繼續解析:

        var shout == compose(exclaim, toUpperCase)== function (x) {return [exclaim, toUpperCase].reduceRight(function(prevalue, curvalue){return curvalue(prevalue);},x)};shout("my name is echo") == [exclaim, toUpperCase].reduceRight(function(prevalue, curvalue){return curvalue(prevalue);},"my name is echo");/*前面說過,如果reduce/reduceRight傳了第二個參數,那么該第二個參數將作為prevalue給callback調用。*//*運算過程如下(reduceRight從右往左)curvalue(prevalue):*/1.toUpperCase("my name is echo");并將結果作為prevalue供下次調用;2.exclaim(toUpperCase("my name is echo"));如此實現了先轉大寫再加感嘆號。
View Code

?

轉載于:https://www.cnblogs.com/eco-just/p/10328522.html

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

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

相關文章

印度評論九章量子計算機,張禮立:中國 “九章”量子計算機到底厲害在哪?...

【背景信息】12月4日&#xff0c;《科學》雜志公布了中國“九章”的重大突破。 這臺由中國科學技術大學潘建偉、陸朝陽等學者研制的76個光子的量子計算原型機&#xff0c;推動全球量子計算的前沿研究達到一個新高度。盡管距離實際應用仍有漫漫長路&#xff0c;但成功實現了“量…

手機web網頁制作的認識(有關meta標簽)

近日以來一直在看JQuery Mobile 一個手機開發框架&#xff0c;說實話真的很頭疼的~~~~ 因為里面有很多的屬性、方法和事件~~~ 下面是手機網頁的一些認識&#xff1a; 一、<meta name"viewport" id"viewport" content"widthdevice-width, initial-s…

包打包和解析過程 unity_Unity學習—資源管理概覽

本文介紹了 Unity 常用四種默認路徑&#xff0c;以及 AssetDataBase、Resources、AssetBundle 和目前最新的 Addressable 四種資源管理方式文中所有 API 均以版本 2019.3 為準本文原地址&#xff1a;Unity學習—資源管理概覽資源路徑Application.dataPath官方文檔只讀&#xff…

graphql tools_聲明式GraphQL:編寫更少的代碼,并使用graphql-tools完成更多工作

graphql toolsI’ve been working with GraphQL for a few months now, but only recently began using Apollo’s graphql-tools library. After learning a few idioms, I am able to mock up a functional API quickly. This is largely due to its low-code, declarative a…

用idea搭建SSM項目,原來這么簡單

目錄 前言軟件環境創建項目數據庫文件配置文件pom.xmllog4j.propertiesjdbc.propertiesapplicationContext.xmlspring-mvc.xmlweb.xml運行項目編寫代碼前言 前陣子突發奇想&#xff0c;想學習下SpringMVC的源碼&#xff0c;于是打算用idea搭建一個簡易的maven版SSM案例&#xf…

浙江理工大學計算機組成原理試卷,浙江理工大學計算機組成原理設計試題.doc...

計算機組成原理課程設計報告2013/2014第二學期指導教師&#xff1a;許建龍 張芳班級&#xff1a;12計科2班姓名&#xff1a;學號&#xff1a; 計算機組成原理大型實驗任務書(計算機12級1、2、3班和實驗班)實驗目的&#xff1a;深入了解計算機各種指令的執行過程&#xff0c;以及…

mac vagrant 虛擬機nfs掛載點

需求&#xff1a;在mac 上安裝了虛擬機&#xff0c;虛擬機系統為centos6.5&#xff0c;現在希望講虛擬機上點目錄通過nfs共享給mac使用 下面主要描述通過nfs共享目錄給mac調用的過程 過程參考網址&#xff1a; http://www.moqifei.com/archives/1534 &#xff08;我主要參考的這…

nodejs中require的路徑是一個文件夾時發生了什么

node中使用require的時候如果路徑是一個文件夾時&#xff0c;或者特殊的情況require(..);require(.); 這是node實戰這本書里說的情況&#xff0c;但是我在node6.9版本中發現不完全是這樣&#xff0c;可能是后來做了修改。下面說說在6.9下require路徑的過程。 這里以require(.)說…

python調用ctypes中windll中的方法超時處理_python中使用ctypes調用MinGW生成的動態鏈接庫(dll)...

關于gcc編譯dll的我就不說了&#xff0c;網上舉例一大堆&#xff0c;下面以g為例。假設有一個test.cpp文件如下&#xff1a;extern "C" {__declspec(dllexport) double add(double x,double y);}double add(double x,double y){return xy;}在MinGW中使用g編譯&#x…

慣用過程模型_慣用的Ruby:編寫漂亮的代碼

慣用過程模型Ruby is a beautiful programming language.Ruby是一種美麗的編程語言。 According to Ruby’s official web page, Ruby is a:根據Ruby的官方網頁&#xff0c;Ruby是&#xff1a; “dynamic, open source programming language with a focus on simplicity and …

采用晶體管為基本元件的計算機發展階段是,計算機應用基礎知識點

第一章 計算機基礎知識1、計算機發展階段第一代&#xff1a;電子管計算機采用電子管為基本元件&#xff0c;設計使用機器語言或匯編語言。要用于科學和工程計算 第二代&#xff1a;晶體管計算機采用晶體管為基本元件&#xff0c;程序設計采用高級語言&#xff0c;出現了操作系統…

springcloud系列三 搭建服務模塊

搭建服務模塊為了模擬正式開發環境,只是少寫了service層直接在controller里面直接引用,直接上圖和代碼:更為方便: 創建完成之后加入配置: pom.xml文件: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM…

P1801 黑匣子_NOI導刊2010提高(06)

題目描述 Black Box是一種原始的數據庫。它可以儲存一個整數數組&#xff0c;還有一個特別的變量i。最開始的時候Black Box是空的&#xff0e;而i等于0。這個Black Box要處理一串命令。 命令只有兩種&#xff1a; ADD(x):把x元素放進BlackBox; GET:i加1&#xff0c;然后輸出Bla…

MySql模糊查詢

常規like的使用限制&#xff1a; 1. like %keyword &#xff1a;索引失效&#xff0c;使用全表掃描。但可以通過翻轉函數like前模糊查詢建立翻轉函數索引走翻轉函數索引&#xff0c;不走全表掃描。 2. like keyword% &#xff1a;索引有效。 3. like %keyword% &#xff1a;索引…

python psycopg2使用_python?操作數據庫:psycopg2的使用

1 conn psycopg2.connect(database"testdb", user"postgres",password"cohondob", host"127.0.0.1", port"5432")這個API打開一個連接到PostgreSQL數據庫。如果成功打開數據庫時&#xff0c;它返回一個連接對象。2cursor c…

軟件測試人員棘手的問題,èí?t2aê?μ???ê??êìa£oè?o?±ü?a???′ìá??è±?Y...

¡¡¡¡£££©£¡££¡££££©©£¡¡¡¡¡BUG£££¢¡£££¡££¡£¡£——£…

機器學習實用指南_機器學習方法:實用指南

機器學習實用指南by Karlijn Willems通過Karlijn Willems 機器學習方法&#xff1a;實用指南 (How Machines Learn: A Practical Guide) You may have heard about machine learning from interesting applications like spam filtering, optical character recognition, and …

本地倉庫settings.xml中使用阿里的倉庫

背景 當前使用eclipse自帶的maven碰到兩個蛋疼的問題&#xff1a; maven在國內使用如果不進行FQ則會痛苦不堪如便秘。maven下載大量jar包導致某盤不夠用&#xff0c;需要換大的分區。因此為了解決這個問題就介紹兩個eclipse配置&#xff1a;maven本地路徑配置和maven外部路徑配…

day6_python之md5加密

#md5是不可逆的&#xff0c;就是沒有辦法解密的 Python內置哈希庫對字符串進行MD5加密的方法-hashlibimport hashlib def my_md5(s,salt): #用函數&#xff0c;為了提高代碼的復用率s ssalt #1.必須是字符串news str(s).encode() #2.字符串需要encode編碼后&#xff0…

異步服務_微服務全鏈路異步化實踐

1. 背景隨著公司業務的發展&#xff0c;核心服務流量越來越大&#xff0c;使用到的資源也越來越多。在微服務架構體系中&#xff0c;大部分的業務是基于Java 語言實現的&#xff0c;受限于Java 的線程實現&#xff0c;一個Java 線程映射到一個kernel 線程&#xff0c;造成了高并…