2017-02-22 35 views
0

我定義了一個對象,如下所示:如何更新對象屬性的枚舉?

var obj = {}; 
 
var name = "nonenumerable"; 
 
var value = "hello world"; 
 

 
Object.defineProperty(obj, name, {value: value, 
 
    writable : true, 
 
    enumerable : false, 
 
    configurable : true 
 
}); 
 

 
console.log(obj); 
 
//output in code snippet console: {} 
 
//output in browser console: { nonenumerable: "hello world" }

現在我想將對象存儲到我的本地存儲與

localStorage.setItem("localObj", JSON.stringify(obj)); 

我知道,一個JSONObjects不包括「非枚舉「,因此我的財產不存儲。我的問題是,我使用該對象作爲一種「哈希表」。

var obj = { 
 
    1: { id: 1, start: 3, end: 6 }, 
 
    2: { id: 2, start: 5, end: 8 }, 
 
    3: { id: 3, start: 2, end: 4 } 
 
}; 
 
Object.defineProperty(obj, "all", {value: {}, 
 
    writable : true, 
 
    enumerable : false, 
 
    configurable : true 
 
}); 
 
obj.all.start = 0; 
 
obj.all.end = 10; 
 

 
function setStart(id, add){ 
 
    if(add) obj[id].start += 1; 
 
    else obj[id].start -= 1 
 
    updateContent("start", id, obj[id].start); 
 
} 
 

 
function setAllStart(start, add){ 
 
    if(add) obj.all.start += 1; 
 
    else obj.all.start -= 1 
 
    updateContent("start", "all", obj.all.start); 
 
    for(id in obj){ 
 
    obj[id].start = obj.all.start; 
 
    updateContent("start", id, obj[id].start); 
 
    } 
 
} 
 

 
function setEnd(id, add){ 
 
    if(add) obj[id].end += 1; 
 
    else obj[id].end -= 1 
 
    updateContent("end", id, obj[id].end); 
 
} 
 

 
function setAllEnd(start, add){ 
 
    if(add) obj.all.end += 1; 
 
    else obj.all.end -= 1 
 
    updateContent("end", "all", obj.all.end); 
 
    for(id in obj){ 
 
    obj[id].end = obj.all.end; 
 
    updateContent("end", id, obj[id].end); 
 
    } 
 
} 
 

 
function updateContent(selector, id, content){ 
 
    document.querySelector("#" + selector + "-" + id).innerHTML = content; 
 
}
.value { 
 
    display: inline-block; 
 
}
<div> 
 
    AllStart: 
 
    <button type="button" onclick="setAllStart(3, false);">-</button> 
 
    <div id="start-all" class="value">0</div> 
 
    <button type="button" onclick="setAllStart(3, true);">+</button> 
 
</div> 
 
<div> 
 
    AllEnd: 
 
    <button type="button" onclick="setAllEnd(3, false);">-</button> 
 
    <div id="end-all" class="value">10</div> 
 
    <button type="button" onclick="setAllEnd(3, true);">+</button> 
 
</div> 
 
<div> 
 
    Start 1: 
 
    <button type="button" onclick="setStart(1, false);">-</button> 
 
    <div id="start-1" class="value">3</div> 
 
    <button type="button" onclick="setStart(1, true);">+</button> 
 
</div> 
 
<div> 
 
    End 1: 
 
    <button type="button" onclick="setEnd(1, false);">-</button> 
 
    <div id="end-1" class="value">6</div> 
 
    <button type="button" onclick="setEnd(1, true);">+</button> 
 
</div> 
 
<div> 
 
    Start 2: 
 
    <button type="button" onclick="setStart(2, false);">-</button> 
 
    <div id="start-2" class="value">5</div> 
 
    <button type="button" onclick="setStart(2, true);">+</button> 
 
</div> 
 
<div> 
 
    End 2: 
 
    <button type="button" onclick="setEnd(2, false);">-</button> 
 
    <div id="end-2" class="value">8</div> 
 
    <button type="button" onclick="setEnd(2, true);">+</button> 
 
</div> 
 
<div> 
 
    Start 3: 
 
    <button type="button" onclick="setStart(3, false);">-</button> 
 
    <div id="start-3" class="value">2</div> 
 
    <button type="button" onclick="setStart(3, true);">+</button> 
 
</div> 
 
<div> 
 
    End 3: 
 
    <button type="button" onclick="setEnd(3, false);">-</button> 
 
    <div id="end-3" class="value">4</div> 
 
    <button type="button" onclick="setEnd(3, true);">+</button> 
 
</div>

我的問題:

1)我可以更新我的財產defineProperty後enumerabletrue

2)如果在for-loop中定義爲obj.all = {}而沒有if-statement,我可以使用「不可枚舉」鍵嗎?

預先感謝您。

+0

'爲...通過枚舉接口加載in'唯一的 「循環」 - 不是嗎? –

+0

是的。這就是爲什麼我將屬性「all」定義爲「nonenumerable」。 – DomeTune

+0

那麼,這有什麼問題?爲什麼它需要「變得」可枚舉? 'obj.all'具有值'helloworld!' - 如果使用'enumerable:true'創建它 - 前一個循環不會被追溯調用 –

回答

1

助手功能

function load(inp) { 
    var spec = function (o) { 
     Object.defineProperty(o, 'all', { 
      writable: true, 
      enumerable: false, 
      configurable : true, 
      value: o.all || {} 
     }); 
     Object.defineProperty(o, "toString", { 
      value: function() { 
       Object.defineProperty(this, 'all', { enumerable: true}); 
       var ret = JSON.stringify(this); 
       Object.defineProperty(this, 'all', { enumerable: false}); 
       return ret; 
      } 
     }); 
     return o; 
    }; 
    return spec(typeof inp == "string" ? JSON.parse(inp) : inp); 
} 

可以初始化對象這樣

var obj = load({ 
    1: { id: 1, start: 3, end: 6 }, 
    2: { id: 2, start: 5, end: 8 }, 
    3: { id: 3, start: 2, end: 4 } 
}); 
obj.all.start = 0; 
obj.all.end = 10; 

也不像這個

var obj1 = load({ 
    1: { id: 1, start: 3, end: 6 }, 
    2: { id: 2, start: 5, end: 8 }, 
    3: { id: 3, start: 2, end: 4 }, 
    all: { 
     start: 0, 
     end: 10 
    } 
}); 

存儲它

localStorage.setItem('testing', obj) 

從存儲

var obj2 = load(localStorage.getItem('testing')); 

console.log(obj.toString() == obj2.toString()); 
// true 
+0

這是一個非常好的解決方案,助手功能非常好。我已經解決了這個問題,但這與我的解決方案非常相似。 – DomeTune

1

Object.defineProperty()也可用於修改現有屬性的描述符。爲了您的使用情況下,更好的形式給出。將序列化原始對象的副本:

var open = {}; 
Object.assign(open, obj); 
open.all = obj.all; 
localStorage.setItem("localObj", JSON.stringify(open)); 
+0

感謝您的提示,我可以修改現有屬性的描述符。不幸的是我不能使用該對象的副本,因爲當我加載它時,我需要將該對象與克隆合併。 – DomeTune

0

正如ccprog的答案我可以用它來Object.defineProperty()修改我的對象屬性提及。

var obj = {}; 
 
var name = "nonenumerable"; 
 
var value = "hello world"; 
 

 
Object.defineProperty(obj, name, {value: value, 
 
    writable : true, 
 
    enumerable : false, 
 
    configurable : true 
 
}); 
 

 
console.log(obj); 
 
//output in code snippet console: {} 
 
//output in browser console: { nonenumerable: "hello world" } 
 

 

 
Object.defineProperty(obj, name, { 
 
    enumerable : true 
 
}); 
 
console.log(obj);