<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      深入理解JavaScript系列(50):Function模式(下篇)

      2012-07-24 09:07  湯姆大叔  閱讀(23312)  評論(23)    收藏  舉報

      介紹

      本篇我們介紹的一些模式稱為初始化模式和性能模式,主要是用在初始化以及提高性能方面,一些模式之前已經提到過,這里只是做一下總結。

      立即執行的函數

      在本系列第4篇的《立即調用的函數表達式》中,我們已經對類似的函數進行過詳細的描述,這里我們只是再舉兩個簡單的例子做一下總結。

      // 聲明完函數以后,立即執行該函數
      (function () {
          console.log('watch out!');
      } ());
      
      //這種方式聲明的函數,也可以立即執行
      !function () {
          console.log('watch out!');
      } ();
      
      // 如下方式也都可以哦
      ~function () { /* code */ } ();
      -function () { /* code */ } ();
      +function () { /* code */ } ();

      立即執行的對象初始化

      該模式的意思是指在聲明一個對象(而非函數)的時候,立即執行對象里的某一個方法來進行初始化工作,通常該模式可以用在一次性執行的代碼上。

      ({
          // 這里你可以定義常量,設置其它值
          maxwidth: 600,
          maxheight: 400,
      
          //  當然也可以定義utility方法
          gimmeMax: function () {
              return this.maxwidth + "x" + this.maxheight;
          },
      
          // 初始化
          init: function () {
              console.log(this.gimmeMax());
              // 更多代碼...
          }
      }).init();  // 這樣就開始初始化咯

      分支初始化

      分支初始化是指在初始化的時候,根據不同的條件(場景)初始化不同的代碼,也就是所謂的條件語句賦值。之前我們在做事件處理的時候,通常使用類似下面的代碼:

      var utils = {
          addListener: function (el, type, fn) {
              if (typeof window.addEventListener === 'function') {
                  el.addEventListener(type, fn, false);
              } else if (typeof document.attachEvent !== 'undefined') {
                  el.attachEvent('on' + type, fn);
              } else {
                  el['on' + type] = fn;
              }
          },
          removeListener: function (el, type, fn) {
          }
      };

      我們來改進一下,首先我們要定義兩個接口,一個用來add事件句柄,一個用來remove事件句柄,代碼如下:

      var utils = {
          addListener: null,
          removeListener: null
      };

      實現代碼如下:

      if (typeof window.addEventListener === 'function') {
          utils.addListener = function (el, type, fn) {
              el.addEventListener(type, fn, false);
          };
      } else if (typeof document.attachEvent !== 'undefined') { // IE
          utils.addListener = function (el, type, fn) {
              el.attachEvent('on' + type, fn);
          };
          utils.removeListener = function (el, type, fn) {
              el.detachEvent('on' + type, fn);
          };
      } else { // 其它舊瀏覽器
          utils.addListener = function (el, type, fn) {
              el['on' + type] = fn;
          };
          utils.removeListener = function (el, type, fn) {
              el['on' + type] = null;
          };
      }

      用起來,是不是就很方便了?代碼也優雅多了。

      自聲明函數

      一般是在函數內部,重寫同名函數代碼,比如:

      var scareMe = function () {
          alert("Boo!");
          scareMe = function () {
              alert("Double boo!");
          };
      };

      這種代碼,非常容易使人迷惑,我們先來看看例子的執行結果:

      // 1. 添加新屬性
      scareMe.property = "properly";
      // 2. scareMe賦與一個新值
      var prank = scareMe;
      // 3. 作為一個方法調用
      var spooky = {
          boo: scareMe
      };
      // 使用新變量名稱進行調用
      prank(); // "Boo!"
      prank(); // "Boo!"
      console.log(prank.property); // "properly"
      // 使用方法進行調用
      spooky.boo(); // "Boo!"
      spooky.boo(); // "Boo!"
      console.log(spooky.boo.property); // "properly"

      通過執行結果,可以發現,將定于的函數賦值與新變量(或內部方法),代碼并不執行重載的scareMe代碼,而如下例子則正好相反:

      // 使用自聲明函數
      scareMe(); // Double boo!
      scareMe(); // Double boo!
      console.log(scareMe.property); // undefined

      大家使用這種模式時,一定要非常小心才行,否則實際結果很可能和你期望的結果不一樣,當然你也可以利用這個特殊做一些特殊的操作。

      內存優化

      該模式主要是利用函數的屬性特性來避免大量的重復計算。通常代碼形式如下:

      var myFunc = function (param) {
          if (!myFunc.cache[param]) {
              var result = {};
              // ... 復雜操作 ...
              myFunc.cache[param] = result;
          }
          return myFunc.cache[param];
      };
      
      // cache 存儲
      myFunc.cache = {};

      但是上述代碼有個問題,如果傳入的參數是toString或者其它類似Object擁有的一些公用方法的話,就會出現問題,這時候就需要使用傳說中的hasOwnProperty方法了,代碼如下:

      var myFunc = function (param) {
          if (!myFunc.cache.hasOwnProperty(param)) {
              var result = {};
              // ... 復雜操作 ...
              myFunc.cache[param] = result;
          }
          return myFunc.cache[param];
      };
      
      // cache 存儲
      myFunc.cache = {};

      或者如果你傳入的參數是多個的話,可以將這些參數通過JSON的stringify方法生產一個cachekey值進行存儲,代碼如下:

      var myFunc = function () {
          var cachekey = JSON.stringify(Array.prototype.slice.call(arguments)),
              result;
          if (!myFunc.cache[cachekey]) {
              result = {};
              // ... 復雜操作 ...
              myFunc.cache[cachekey] = result;
          }
          return myFunc.cache[cachekey];
      };
      
      // cache 存儲
      myFunc.cache = {};

      或者多個參數的話,也可以利用arguments.callee特性:

      var myFunc = function (param) {
          var f = arguments.callee,
              result;
          if (!f.cache[param]) {
              result = {};
              // ... 復雜操作 ...
              f.cache[param] = result;
          }
          return f.cache[param];
      };
      
      // cache 存儲
      myFunc.cache = {};

      總結

      就不用總結了吧,大家仔細看代碼就行咯

      同步與推薦

      本文已同步至目錄索引:深入理解JavaScript系列

      深入理解JavaScript系列文章,包括了原創,翻譯,轉載等各類型的文章,如果對你有用,請推薦支持一把,給大叔寫作的動力。

      主站蜘蛛池模板: 亚洲一区二区三区十八禁| 日韩丝袜欧美人妻制服| 国产日韩av二区三区| 国产午夜精品福利视频| 四虎成人在线观看免费| 亚洲精品人成网线在线| 国产盗摄视频一区二区三区| 一二三三免费观看视频| 97精品国产91久久久久久久| 无码任你躁久久久久久老妇| 日韩一区二区三区av在线| 敦化市| 奶头好大揉着好爽视频| 国产精品亚洲а∨天堂2021| 欧美成人看片黄A免费看| 国产成人午夜精品永久免费| 国产精品无码不卡在线播放| 一区二区三区午夜无码视频 | 使劲快高潮了国语对白在线| 精品国产熟女一区二区三区| 制服丝袜美腿一区二区| 国产AV福利第一精品| 久久91精品牛牛| 欧美亚洲综合成人A∨在线 | 91超碰在线精品| 亚洲欧美综合精品成| 免费的很黄很污的视频| 色噜噜在线视频免费观看| 免费无码一区无码东京热| 久草热久草热线频97精品| AI做受???高潮AAAA视频| 激情亚洲一区国产精品| 久久热这里只有精品66| 亚洲中文久久久精品无码| 亚洲www永久成人网站| 最新中文字幕av无码专区不 | 亚洲 欧美 综合 另类 中字| 国产成人啪精品午夜网站| 久久精品久久黄色片看看| 狠狠躁夜夜躁人人爽天天5| 午夜DY888国产精品影院|