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

來源:互聯網
上載者:User
介紹

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

立即執行的函數

在本系列第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 = {};

 

 

轉載:
http://www.cnblogs.com/TomXu

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.