Javascriptg進階函數

來源:互聯網
上載者:User

標籤:引導   應該   argument   操作   prot   提前   特性   處理   記憶體   

Javascript進階函數
  • 惰性載入函數
  • 函數柯裡化
  • 級聯函數

這並不全面,只是幾個主要的。

惰性載入函數

  惰性載入表示函數執行的分支只會在函數第一次掉用的時候執行,在第一次調用過程中,該函數會被覆蓋為另一個按照合適方式執行的函數,這樣任何對原函數的調用就不用再經過執行的分支了。

  寫一個函數用來建立XmlHttpRequest對象,瀏覽器安全色性原因,寫出的代碼通過大量if判斷或者try,catch語句將函數引導到正確代碼處。

程式碼範例:

function createXHR(){    var xhr = null;    try {        // Firefox, Opera 8.0+, Safari,IE7+        xhr = new XMLHttpRequest();    }    catch (e) {        // Internet Explorer         try {            xhr = new ActiveXObject("Msxml2.XMLHTTP");        }        catch (e) {            try {                xhr = new ActiveXObject("Microsoft.XMLHTTP");            }            catch (e) {                xhr = null;            }        }    }    return xhr;} 

  每次調用這個函數的時候,都要先進行瀏覽器能力檢查,首先檢查瀏覽器是否支援內建的XMLHyypRequest對象,如果不支援然後檢查各版本基於ActiveX的XMLHttpRequest,每次調用該函數都是這樣,其實當第一次執行完後,如果瀏覽器支援某個特定XMLHttpRequest對象,那麼下次執行的時候這種支援性並不會改變,沒必要再進行一邊檢測,即使只有一個if語句,執行也肯定比沒有要慢,如果我們可以讓if語句不必每次執行,那麼就可以在頻繁調用的情況下提高執行速度。並且如果在多次createXHR後沒有處理好,還會非常容易造成記憶體流失。解決方案就是惰性載入。在已經判斷出當前瀏覽器是什麼的時候,就讓createXHR == XHR; 

function createXHR(){  var xhr=null;
  if(typeof XMLHttpRequest !=‘undefined‘){   xhr = new XMLHttpRequest(); createXHR=function(){   return new XMLHttpRequest(); } }else{   try {   xhr = new ActiveXObject("Msxml2.XMLHTTP"); createXHR=function(){   return new ActiveXObject("Msxml2.XMLHTTP"); } } catch (e) {   try {   xhr = new ActiveXObject("Microsoft.XMLHTTP"); createXHR=function(){   return new ActiveXObject("Microsoft.XMLHTTP"); } } catch (e) {   createXHR=function(){ return null; } } } } return xhr;}

  在這個惰性載入的createXHR中第一次執行的時候每個分支都會為createXHR重新賦值,覆蓋原函數,返回xhr對象,而第二次執行的時候就會直接調用重寫後的函數,這樣就不必執行每個分支重新做檢測了。

函數柯裡化

  在電腦科學中,柯裡化(英語:Currying),又譯為卡瑞化或加裡化,是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,並且返回接受餘下的參數而且返回結果的新函數的技術。

  說起函數柯裡化,我理解起來確實費了很大一波力,首先對於代碼中的很多部分都不理解,比如slice、call()、apply()【日後會寫這三個】。理解了這些之後自然能夠看懂柯裡化的通用實現:

程式碼範例:

function currying(fn) {    var args = Array.prototype.slice.call(arguments, 1);    return function () {        var innerArgs = Array.prototype.slice.call(arguments);        var finalArgs = args.concat(innerArgs);        console.log (finalArgs);        return fn.apply(this,finalArgs);    };}
    1. 提高適用性

      程式碼範例:

      function square(i) {    return i * i;}function dubble(i) {    return i *= 2;}function map(handeler, list) {    return list.map(handeler);}// 數組的每一項平方map(square, [1, 2, 3, 4, 5]);map(square, [6, 7, 8, 9, 10]);map(square, [10, 20, 30, 40, 50]);// ......// 數組的每一項加倍map(dubble, [1, 2, 3, 4, 5]);map(dubble, [6, 7, 8, 9, 10]);map(dubble, [10, 20, 30, 40, 50]);

      例子中,建立了一個map通用函數,用於適應不同的應用情境。。同時,例子中重複傳入了相同的處理函數:square和dubble。

      應用中這種需要處理的東西會更多。通用性的增強必然帶來適用性的減弱。但是,我們依然可以在中間找到一種平衡。

      看下面,我們利用柯裡化改造一下:

      程式碼範例:

      function square(i) {    return i * i;}function dubble(i) {    return i *= 2;}function map(handeler, list) {    return list.map(handeler);}var mapSQ = currying(map, square);mapSQ([1, 2, 3, 4, 5]);mapSQ([6, 7, 8, 9, 10]);mapSQ([10, 20, 30, 40, 50]);// ......var mapDB = currying(map, dubble);mapDB([1, 2, 3, 4, 5]);mapDB([6, 7, 8, 9, 10]);mapDB([10, 20, 30, 40, 50]);// ......

      柯裡化降低通用性,提高適用性。  

    2. 順延強制

      不斷的柯裡化,累計傳入的參數,最後執行。

      程式碼範例:

      var add = function() {    var _this = this,    _args = arguments    return function() {        if (!arguments.length) {            var sum = 0;            for (var i = 0,c; c = _args[i++];) sum += c;            return sum;        } else {            Array.prototype.push.apply(_args, arguments) 
      return arguments.callee; } }}add(1)(2)(3)(4)();//10

      柯裡化:

      var curry = function(fn) {    var _args = []    return function cb() {        if (arguments.length == 0) {            return fn.apply(this, _args)        }        Array.prototype.push.apply(_args, arguments);        return cb;    }}

        

    3. 固定易變因素

      柯裡化特性決定了它可以提前把易變因素,傳參固定下來,產生一個更明確的應用函數。最典型的代表應用,是bind函數用以固定this這個易變對象。

      Function.prototype.bind = function(context) {    var _this = this,    _args = Array.prototype.slice.call(arguments, 1);    return function() {        return _this.apply(context, _args.concat(Array.prototype.slice.call(arguments)))    }}

但其實我還是沒有那麼透徹的理解函數柯裡化,應該等到其他的知識掌握的更加熟練,理解起來也才會更加容易吧

級聯函數

  級聯函數也叫鏈式函數,方法鏈一般適合對一個對象進行連續操作(集中在一句代碼),一定程度上把相關的屬性都連到一起,減少代碼量,缺點是它佔用了函數的傳回值。

function myclassA(){ this.name=""; this.age=""; this.sex="";}myclassA.prototype={ setname:function(){  this.name="katherine";  return this; }, setage:function(){  this.age="22";  return this; }, setsex:function(){  this.sex=‘girl‘;  return this; }}var me =new myclassA();console.log(me.setname().setage().setsex());// myclassA {name: "katherine", age: "22", sex: "girl"}

  這一篇整整弄了兩天才弄完,但是還是有些搞不懂函數柯裡化,我想只能在日後的開發中,慢慢接觸項目來解鎖理解了【攤手】

 

  

Javascriptg進階函數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.