如何更新对象 属性 的枚举?
How to update the enumerable of an object property?
我定义一个对象如下:
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 不包含 "non enumerables",因此我的 属性 没有被存储。我的问题是我将该对象用作一种 "hashtable"。
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 之后将 属性 的 enumerable
更新为 true
吗?
2) 如果 "nonenumerable" 键在 for-loop
中定义为 obj.all = {}
而没有 if-statement
,我可以跳过它吗?
提前致谢。
Object.defineProperty()
也可用于修改现有 属性 的描述符。对于您的用例,更好的方法是序列化原始对象的副本:
var open = {};
Object.assign(open, obj);
open.all = obj.all;
localStorage.setItem("localObj", JSON.stringify(open));
正如 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);
辅助函数
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
我定义一个对象如下:
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 不包含 "non enumerables",因此我的 属性 没有被存储。我的问题是我将该对象用作一种 "hashtable"。
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 之后将 属性 的 enumerable
更新为 true
吗?
2) 如果 "nonenumerable" 键在 for-loop
中定义为 obj.all = {}
而没有 if-statement
,我可以跳过它吗?
提前致谢。
Object.defineProperty()
也可用于修改现有 属性 的描述符。对于您的用例,更好的方法是序列化原始对象的副本:
var open = {};
Object.assign(open, obj);
open.all = obj.all;
localStorage.setItem("localObj", JSON.stringify(open));
正如 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);
辅助函数
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