2013-02-08 27 views
1

我有以下代碼賦值和在同一行中返回變量

var s = storage('foo'); 
s.bar = 100; 
storage('foo', s); 

storage從某個存儲媒體返回一個對象。然後我改變對象的一個​​屬性的值,並再次將它發送到storage。我的問題是有沒有辦法讓它成爲一個班輪?喜歡的東西

storage('foo', storage('foo').bar = 100); 

但上面的代碼只保存100,而不是整個foo對象。

這裏是storage功能,它存儲在localStorage的,但使得對象存儲,而不是字符串存儲:

function storage(item, value) { 
    if(value!=null) { 
     var result = (storage()) ? storage() : {}; 
     if(item) result[item] = value; 
     return localStorage.setItem('storage', JSON.stringify(result)) 
    } else return (item) ? storage()[item] : JSON.parse(localStorage.getItem('storage')); 
} 

編輯: 所以我結束了以下存儲功能一行變化。但是這不能解釋多維度的用法。所以我會歡迎任何建議。

function storage(item, value, property) { 
    ... 
     if(item) (property) ? result[item][property] = value : result[item] = value; 
    ... 
} 

回答

2

的合理的事情,如果你不能改變storage功能,是創建另一個功能:

function set_storage(obj, prop, val) { 
    var s = storage(obj); 
    obj[prop] = val; 
    storage(obj, s); 
} 

// usage 
set_storage('foo', 'bar', 100); 

如果你可以改變,雖然存儲,這將是一個更好的方法。 jQuery.data的作用類似。

有辦法做到這一點的(幾乎)一行,與comma operator [MDN]的幫助,但它不是漂亮:

var s = storage('foo'); 
storage('foo', (s.bar = 100, s)); 

既然你說storage是你的函數,超載這似乎是一個好方法。它會這樣:

function storage(key, prop, val) { 
    var storage = JSON.parse(localStorage.getItem('storage')); 

    if(arguments.length === 0) { 
     return storage; 
    } 
    else if (arguments.length === 1) { 
     // only one argument passed, return the value with key `key` 
     return storage[key]; 
    } 
    else if (arguments.length === 2) { 
     // set `key` to `prop` (`prop` contains the actual value) 
     storage[key] = prop; 
    } 
    else { 
     // set property `prop` of object in `key` to value `val` 
     storage[key][prop] = val; 
    } 
    localStorage.setItem('storage', JSON.stringify(storage)); 
} 

// Usage 

// get `foo`: 
var foo = storage('foo'); 

// set `foo`: 
storage('foo', {bar: 42}); 

// set foo.bar 
storage('foo', 'bar', 100); 

我希望它給你一些想法。

+0

+1(幾乎)1班輪:) – Matt 2013-02-08 12:02:11

+0

最後一個例子看起來很有趣,它是如何工作的?我有一種感覺,這不會以同樣的方式工作,對吧? 'storage('foo',(storage('foo').bar = 100,storage('foo')));' – Achshar 2013-02-08 12:12:32

+0

@Achshar:你說的對,它不會。逗號運算符從左向右評估它的操作數並返回右操作數的結果。在你的例子中,你永遠不會把改變的對象寫回存儲器,因爲'storage('foo')'從存儲器讀取未修改的對象。 – 2013-02-08 12:15:11

0

作爲storage返回object,那裏有一個(非常)好的機會,你可以做*;

storage('foo').bar = 100; 

console.log(storage('foo').bar); // should give 100. 

...直接,因爲對象是「通過引用傳遞」 - 轉義。


*,這些都不會是這樣一個情況是,其中storage返回對象的副本存儲,而不是對象本身;因此對返回對象的任何更新都不會影響存儲中的對象。

+0

存儲是我自己的函數,它存儲在localStorage的,但使得對象存儲,而不是字符串存儲。所以我不確定是否可以做到。我會用'storage'的來源更新這個問題。 – Achshar 2013-02-08 11:58:53

+0

如果你正在從'localStorage'進行字符串化和解析,這種方法將不起作用。 – Matt 2013-02-08 12:02:35

0

可以使它接受改變物體的功能的功能:

function changeObject(key, func) { 
    var obj = storage(key); 
    func(obj); 
    storage(key, obj); 
} 

changeObject('foo', function (s) { s.bar = 100; });