2012-06-16 58 views
6

我正在處理一些對象,這些對象包含許多要從瀏覽器顯示和處理的數據,我想將它保存在本地存儲中。 爲了節省我用JSON.stringify(),所以一切都變得文本對象,和它運作良好在localstorage中保存一個函數

{ 
"bindingRef": [], 
"primo": { 
    "name": "primo", 
    "modifiable": true, 
    "binded": false, 
    "isInteger": false, 
    "label": "Numero di Primi" 
}, 
"secondo": { 
    "name": "secondo", 
    "modifiable": true, 
    "binded": false, 
    "isInteger": false, 
    "label": "Numero di Secondi" 
} 
} 

現在,我想也通過它轉換爲字符串保存的功能,然後saveing它

JSON.stringify(myFunction.toString()); 

但輸出是這

"savedFunction": "function() {\n\t\t\t\tvar tot = menu.primo.get() * 6 + menu.secondo.get() * 8 + menu.dolce.get() * 4;\n\t\t\t\tif (menu.sconto.get()) {\n\t\t\t\t\treturn tot * 0.90;\n\t\t\t\t} else {\n\t\t\t\t\treturn tot;\n\t\t\t\t}\n\t\t\t}" 

它是保存在本地存儲功能的正確方法還是有更好的方法來做到這一點?如果這是正確的方法,是否有辦法簡單地刪除任何製表符/縮進字符或我應該操縱字符串,例如使用一些正則表達式函數?

+0

你想保存對象字符串化或函數簽名?你期待什麼輸出? – Sarfraz

+0

你爲什麼要保存一個功能?在我看來,沒有「正確」的方式來做到這一點,因爲它根本沒有意義。假設你想保存函數的'.toString()'版本,爲什麼你要刪除標籤(你可以使用'.replace()')來完成? – nnnnnn

回答

5

JS中的函數與許多函數式語言一樣都是閉包:它們在內部包含定義時環境範圍的內容,包括臨時數據(如db或文件句柄)。

這不是一個好主意,因爲這可能會導致由於JSON反序列化行爲而導致的問題,所以您必須檢查函數被封裝和什麼是自定義。

有關更多信息,另請參閱此SO thread

+0

有用的鏈接和有用的答案,我會盡量避免保存一個功能。謝謝 – Naigel

1

您可以將函數放在一個對象中,並使用我創建的函數storage.set和storage.get來代替localStorage.set和localStorage.get (localStorage不允許添加函數,與JSON不同)

storage.set將在使用localStorage.setItem()之前對包含函數的對象進行字符串化。
storage.get將在使用localStorage.getItem()之後解析包含函數的對象。

我修改了函數JSON.stringify和JSON.parse以便能夠處理函數,因此您可以在代碼的其他部分使用它而不更改函數名稱。我附加了一個2的原始功能,所以我可以在更新的功能中使用它們。

JSON.stringify2 = JSON.stringify; 
JSON.parse2 = JSON.parse; 

JSON.stringify = function(value) { 
    return JSON.stringify2(value, function(key, val) { 
     return (typeof val === 'function') ? val.toString().replace(/\t|\n/g, '') : val; 
    }); 
} 

JSON.parse = function(value) { 
    return JSON.parse2(value, function(key, val) { 
     if (typeof val === 'string') { 
      var regex = /^function\s*\([^()]*\)\s*{.*}$/; 

      if (regex.exec(val) !== null) 
       return eval('key = ' + val); 
      else 
       return val; 
     } else 
      return val; 
    }); 
} 

var storage = {}; 

storage.set = function(key, value) { 
    if (typeof value === 'object') 
     value = JSON.stringify(value); 

    localStorage.setItem(key, value); 
} 

storage.get = function(key) { 
    var value = localStorage.getItem(key); 

    try { 
     return JSON.parse(value); 
    } catch (e) { 
     return value; 
    } 
} 
+0

壓倒一切的本地人是一個不好的習慣。考慮創建新的功能。 – neeh