2013-04-22 20 views
1

我正在寫一個函數來存儲畫布模式。如果畫布圖案被請求且存在,則返回對畫布的引用,否則首先創建畫布,然後返回引用。我第一次嘗試是將這些畫布引用添加到一個單獨的全局變量,但後來我將它改爲將它們添加到函數中(因爲這節省了一個變量)。可能隱藏函數屬性,以便在函數外部看不到它?

但是,我能夠從代碼中的任何位置讀取屬性(無需調用該函數)。這不是一個大問題,但我想知道它是否可以隱藏(所以,只有一個調用允許通過返回訪問屬性)。

alert(myFunction("keyOne")); // "keyOne " + timestamp of now 
alert(myFunction("keyTwo")); 

alert(myFunction("keyOne")); // same as above, because there it was created 
alert(myFunction("keyTwo")); 

alert(myFunction.keyOne); // can read it without calling the function, is it possible to hide it? 

function myFunction(myKey) 
{ 
    if (!(myFunction.hasOwnProperty(myKey))) { myFunction[myKey] = myKey + " " + Date(); } 
    return myFunction[myKey]; 
} 

編輯:我不知道接受哪個答案。添加一個變量就是我想要避免的事情。此外,它還增加了很多讓代碼難以閱讀的代碼(但它可能是唯一的方法)。如果這是真的,我會像這樣離開它。可讀性對我來說非常重要。

回答

1

你可以捕捉鍵和值的地圖中關閉,而不是將其設置爲函數對象的靜態屬性:

var myFunction = (function() { 

    var keys = {}; 

    return function (myKey) { 
     if (!keys.hasOwnProperty(myKey)) { 
      keys[myKey] = myKey + " " + Date(); 
     } 
     return keys[myKey]; 
    }; 

}()); 

,似乎被分配到myFunction的函數表達式立即被調用,所以它的返回值實際上是被賦值的。它的返回值恰好是另一個函數,所以myFunction現在包含對該內部返回函數的引用。

由於返回的函數包含對父範圍中聲明的變量keys的引用,所以一旦包含它的函數返回,該變量就不能被垃圾回收。你已經創建了一個閉包,可以保留對keys的引用,儘管keys本身不再可以直接訪問。

1

你可以這樣做。

只需創建一個快速調用的函數表達式來實現閉包,該閉包將持有對包含myFunction操作數據的對象的引用。

var myFunction; 
(function() { 
    var inner = {}; 

    myFunction = function (myKey) { 
     if (!(inner.hasOwnProperty(myKey))) { inner[myKey] = myKey + " " + Date(); } 
     return inner[myKey]; 
    } 
}()); 
+1

每次調用myFunction函數時,都會重置'inner',這會使點失敗。 – 2013-04-22 10:33:00

+1

提交快。現在已經糾正了。 – 2013-04-22 10:33:50

1

你可以將其隱藏的匿名函數內部:

(function(ns) { 

    var store = {}; 

    ns.myFunction = function(myKey) { 
     if (!store.hasOwnProperty(myKey)) { 
      store[myKey] = myKey + ' ' + Date(); 
     } 
     return store[myKey]; 
    } 
}(this)); 

我隱在包裝函數傳遞window,在其下方的功能應該被定義的「命名空間」。無法從外部到達store變量。

相關問題