成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

JavaScript 設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)筆記

FingerLiu / 1286人閱讀

摘要:設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)筆記最近利用碎片時(shí)間在上面閱讀設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)這本書(shū),剛開(kāi)始閱讀前兩章內(nèi)容,和大家分享下我覺(jué)得可以在項(xiàng)目中用的上的一些筆記。事件綁定暫時(shí)這么多,以后會(huì)不定期更新一些關(guān)于我讀這本書(shū)的筆記內(nèi)容

JavaScript 設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)筆記

最近利用碎片時(shí)間在 Kindle 上面閱讀《JavaScript 設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)》這本書(shū),剛開(kāi)始閱讀前兩章內(nèi)容,和大家分享下我覺(jué)得可以在項(xiàng)目中用的上的一些筆記。

我的 github 項(xiàng)目會(huì)不定時(shí)更新,有需要的同學(xué)可以移步到我的 github 中去查看源碼:https://github.com/lichenbuliren/design-mode-notes

1、currying 函數(shù)柯里化

currying 又稱部分求值。一個(gè) currying 的函數(shù)首先會(huì)接受一些參數(shù),接受了這些參數(shù)之后,該函數(shù)并不會(huì)立即求值,而是繼續(xù)返回另外一個(gè)函數(shù),將剛才傳入的參數(shù)在函數(shù)形成的閉包中被保存起來(lái)。待到函數(shù)被真正需要求值的時(shí)候,之前傳入的所有參數(shù)都會(huì)被一次性的用于求值。

假設(shè)我們需要編寫(xiě)一個(gè)計(jì)算每個(gè)月開(kāi)銷(xiāo)的函數(shù),在每天結(jié)束之前,我們要記錄每天花掉了多少錢(qián)。

通用 currying 函數(shù):

var currying = function(fn) {
  var args = [];

  return function() {
    if (arguments.length === 0) {
      return fn.apply(this, args);
    } else {
      [].push.apply(args, arguments);
      // 返回函數(shù)本身,這里指向 return 后面的匿名函數(shù)!
      return arguments.callee;
    }
  }
};

var cost = (function() {
  // 閉包存儲(chǔ)最后的值
  var money = 0;

  return function() {
    for (var i = 0, len = arguments.length; i < len; i++) {
      money += arguments[i];
    }

    return money;
  }
})();

// 轉(zhuǎn)化成 currying 函數(shù)
// 這個(gè)時(shí)候,閉包內(nèi)部的 fn 指向真正的求值函數(shù)
// 也就是 cost 自運(yùn)行的時(shí)候返回的匿名函數(shù)
var cost = currying(cost);

cost(200);
cost(300);
cost(500);

// 求值輸出
console.log(cost());
2、uncurrying 函數(shù)
Function.prototype.uncurrying = function() {
  // 此時(shí) selft 是后面例子中的 Array.prototype.push;
  var self = this;

  return function() {
    // arguments: { "0": { "0": 1, length: 1 }, "1": 2 }
    var obj = Array.prototype.shift.call(arguments);
    return self.apply(obj, arguments);
  }
};

// 另外一種實(shí)現(xiàn)方式
Function.prototype.uncurrying = function() {
  var self = this;

  return function() {
    return Function.prototype.call.apply(self, arguments);
  }
};

var push = Array.prototype.push.uncurrying();

var obj = {
  "length": 1,
  "0": 1
};

push(obj, 2);
console.log(obj);
3、函數(shù)節(jié)流

JavaScript 中的函數(shù)大多數(shù)情況下都是由用戶主動(dòng)調(diào)用觸發(fā)的,除非是函數(shù)本身的實(shí)現(xiàn)不合理,否則我們一般不會(huì)遇到跟性能相關(guān)的問(wèn)題。但是在一些少數(shù)情況下,函數(shù)的觸發(fā)不是有由用戶直接控制的。在這些場(chǎng)景下,函數(shù)有可能被非常頻繁的調(diào)用,而造成大的性能問(wèn)題。

函數(shù)被頻繁調(diào)用的場(chǎng)景:

window.onresize 事件

mousemove 事件

上傳進(jìn)度

函數(shù)節(jié)流原理

上面三個(gè)提到的場(chǎng)景,可以發(fā)現(xiàn)它們面臨的共同問(wèn)題是函數(shù)被觸發(fā)的頻率太高。

比如我們?cè)?window.onresize 事件中要打印當(dāng)前瀏覽器窗口大小,在我們拖拽改變窗口大小的時(shí)候,控制臺(tái)1秒鐘進(jìn)行了 10 次。而我們實(shí)際上只需要 2 次或者 3 次。這就需要我們按時(shí)間段來(lái)忽略掉一些事件請(qǐng)求,比如確保在 500ms 內(nèi)打印一次。很顯然,我們可以借助 setTimeout 來(lái)完成。

函數(shù)節(jié)流實(shí)現(xiàn)
/**
 * 函數(shù)節(jié)流實(shí)現(xiàn)
 * @param  {Function} fn       需要節(jié)流執(zhí)行的函數(shù)
 * @param  {[type]}   interval 事件執(zhí)行間隔時(shí)間,單位 ms
 * @return {[type]}            [description]
 */
var throttle = function(fn, interval) {
  var _self = fn,
      timer,
      firstTime = true;

  console.log(_self);

  return function() {
    var args = arguments,
        _me = this;  // 這里代表當(dāng)前的匿名函數(shù)

    console.log(_me);

    if (firstTime) {
      _self.apply(_me, args);
      return firstTime = false;
    }

    if (timer) {
      return false;
    }

    timer = setTimeout(function() {
      clearTimeout(timer);
      timer = null;
      _self.apply(_me, args);
    }, interval || 500);
  };
};

window.onresize = throttle(function() {
  console.log("test");
}, 500);
4、分時(shí)函數(shù)

我們經(jīng)常會(huì)遇到這么一種情況,某些函數(shù)確實(shí)是用戶主動(dòng)調(diào)用的,但是因?yàn)橐恍┛陀^原因,這些函數(shù)會(huì)嚴(yán)重地影響頁(yè)面性能。

一個(gè)例子就是創(chuàng)建 WebQQ 的 QQ 好友列表。列表中通常會(huì)有成百上千個(gè)好友,如果一個(gè)好友用一個(gè)節(jié)點(diǎn)來(lái)表示,當(dāng)我們?cè)陧?yè)面中渲染這個(gè)列表的時(shí)候,可能要一次性往頁(yè)面中創(chuàng)建成百上千個(gè)節(jié)點(diǎn)。

在短時(shí)間內(nèi)往頁(yè)面中大量添加 DOM 節(jié)點(diǎn)顯然也會(huì)讓瀏覽器吃不消,我們看到的結(jié)果往往就是瀏覽器的卡頓甚至假死。所以我們需要一個(gè)分時(shí)函數(shù)來(lái)解決這個(gè)問(wèn)題

/**
 * 分時(shí)函數(shù)例子
 * 以創(chuàng)建 WebQQ 列表為例
 * @param  {[type]}   data     函數(shù)執(zhí)行需要用到的數(shù)據(jù)
 * @param  {Function} fn       真正需要分時(shí)執(zhí)行的函數(shù)
 * @param  {[type]}   count    每次創(chuàng)建一批節(jié)點(diǎn)的數(shù)量
 * @param  {[type]}   interval 函數(shù)執(zhí)行間隔
 * @return {[type]}            [description]
 */
var timeChunk = function(data, fn, count, interval) {
  var t;

  var len = data.length;

  var start = function() {
    for (var i = 0; i < Math.min(count || 1, data.length); i++) {
      var obj = data.shift();
      fn(obj);
    }
  }

  return function() {
    t = setInterval(function() {
      if (data.length === 0) {
        return clearInterval(t);
      }

      start();
    }, interval);
  }
}
5、惰性加載函數(shù)

以創(chuàng)建事件綁定函數(shù)為例:
在進(jìn)入第一個(gè)條件分支之后,在函數(shù)內(nèi)部重寫(xiě)這個(gè)函數(shù),重寫(xiě)之后,就是我們所需要的函數(shù),在下一次進(jìn)入的時(shí)候,就不再需要判斷了。

/**
 * 事件綁定
 * @param {[type]} el      [description]
 * @param {[type]} type    [description]
 * @param {[type]} handler [description]
 */
var addEvent = function(el, type, handler) {
  if (window.addEventListener) {
    addEvent = function(el, type, handler) {
      el.addEventListener(type, handler, false);
    }
  } else if (window.attachEvent) {
    addEvent = function(el, type, handler) {
      el.attachEvent("on" + type, handler);
    }
  }

  addEvent(el, type, handler);
}
Q&A

暫時(shí)這么多,以后會(huì)不定期更新一些關(guān)于我讀這本書(shū)的筆記內(nèi)容!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/86407.html

相關(guān)文章

  • 代碼書(shū)寫(xiě)優(yōu)化(javaScript設(shè)計(jì)模式開(kāi)發(fā)實(shí)踐--讀書(shū)筆記

    摘要:獨(dú)立出來(lái)的函數(shù)更加容易被改寫(xiě),減少維護(hù)成本。例如一個(gè)分頁(yè)函數(shù),函數(shù)接受一個(gè)表示挑戰(zhàn)頁(yè)碼,在跳轉(zhuǎn)前需要判斷是否在有效的取值范圍。面向?qū)ο笤O(shè)計(jì)鼓勵(lì)將行為分布在合理數(shù)量的更小對(duì)象之中。 這是《 javaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐 》一書(shū)的最后一章代碼重構(gòu)。 以下的一些方法不是必須嚴(yán)格遵守的標(biāo)準(zhǔn),選擇實(shí)踐哪些,以及如何實(shí)現(xiàn)這都需根據(jù)情況而定(是不是有充足時(shí)間) 提煉函數(shù) 如果在函數(shù)中有一...

    geekidentity 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式開(kāi)發(fā)實(shí)踐讀書(shū)筆記

    摘要:訂閱模式的一個(gè)典型的應(yīng)用就是后面會(huì)寫(xiě)一篇相關(guān)的讀書(shū)筆記。享元模式享元模式的核心思想是對(duì)象復(fù)用,減少對(duì)象數(shù)量,減少內(nèi)存開(kāi)銷(xiāo)。適配器模式對(duì)目標(biāo)函數(shù)進(jìn)行數(shù)據(jù)參數(shù)轉(zhuǎn)化,使其符合目標(biāo)函數(shù)所需要的格式。 設(shè)計(jì)模式 單例模式 JS的單例模式有別于傳統(tǒng)面向?qū)ο笳Z(yǔ)言的單例模式,js作為一門(mén)無(wú)類(lèi)的語(yǔ)言。使用全局變量的模式來(lái)實(shí)現(xiàn)單例模式思想。js里面的單例又分為普通單例和惰性單例,惰性單例指的是只有這個(gè)實(shí)例...

    Panda 評(píng)論0 收藏0
  • 《高性能JavaScript讀書(shū)筆記

    摘要:除此以外,讓元素脫離文檔流也是一個(gè)很好的方法。因?yàn)樵匾坏┟撾x文檔流,它對(duì)其他元素的影響幾乎為零,性能的損耗就能夠有效局限于一個(gè)較小的范圍。講完重排與重繪,往元素上綁定事件也是引起性能問(wèn)題的元兇。高性能這本書(shū)非常精致,內(nèi)容也非常豐富。 showImg(https://segmentfault.com/img/bVJgbt?w=600&h=784); 入手《高性能JavaScript》一...

    W_BinaryTree 評(píng)論0 收藏0
  • 《編寫(xiě)可維護(hù)的 JavaScript讀書(shū)筆記

    摘要:最近閱讀了編寫(xiě)可維護(hù)的,在這里記錄一下讀書(shū)筆記。禁止使用,,,的字符串形式。避免使用級(jí)事件處理函數(shù)。讓事件處理程序成為接觸到對(duì)象的唯一函數(shù)。檢測(cè)函數(shù)是檢測(cè)檢測(cè)函數(shù)的最佳選擇。為特定瀏覽器的特性進(jìn)行測(cè)試,并僅當(dāng)特性存在時(shí)即可應(yīng)用特性檢測(cè)。 最近閱讀了《編寫(xiě)可維護(hù)的 JavaScript》,在這里記錄一下讀書(shū)筆記。書(shū)中主要基于三個(gè)方向來(lái)講解怎么增加代碼的可維護(hù)性:編程風(fēng)格、編程實(shí)踐、自動(dòng)化...

    tuniutech 評(píng)論0 收藏0
  • javascript 的 eval()——編寫(xiě)可維護(hù)的javascript讀書(shū)筆記

    摘要:盡管在類(lèi)庫(kù)中,可能會(huì)經(jīng)常用到通常和操作有關(guān),另外三種用法即使也非常罕見(jiàn)。一個(gè)通用的原則是,禁止使用,并且只在別無(wú)他法時(shí)使用,。和也是可以使用的,但不要用字符串形式而要用函數(shù) 再javascript中,eval()的參數(shù)是一個(gè)字符串,eval()會(huì)將傳入的字符串當(dāng)做代碼來(lái)執(zhí)行,開(kāi)發(fā)者可以通過(guò)這個(gè)函數(shù)來(lái)載入外部的javascript代碼,活著隨機(jī)生成Javascript代碼并執(zhí)行它,比如:...

    lemon 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<