2017-02-22 38 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);