I would like to be able to call keys(), values(), and items() directly on the object, as a sort of shortform of Object.keys|values|entries(...). Here is what I have thus far:
let o = {
a: 1,
b: 2,
keys() {return Object.keys(this)},
values() {return Object.values(this)},
items() {return Object.entries(this)}
};
for (let k of o.keys()) console.log(k);
for (let v of o.values()) console.log(v);
for (let [k,v] of o.items()) console.log(k,v);
It seems to get what what I want with the exception of I don't want that property to be enumerable. Two things related to this:
What would be the proper way to make the item non-enumerable (so only a and b show up as the keys)? Would the following be good enough?
for (let prop of ['keys', 'values', 'items'])
Object.defineProperty(o, prop, {enumerable: false})
// or
['keys','values','items'].forEach((prop,idx) => Object.defineProperty(o, prop, {enumerable: false}));
Would the above (what I think is a convenience method) be considered a bad idea, and if so why?
You could add the helper methods to the Object.prototype object (basically the parent of all javascript objects) so that all objects have .keys(), .values(), and .entries() methods.
const obj = {
a: 1,
b: 2
};
for (let prop of ['keys', 'values', 'entries']) {
Object.defineProperty(Object.prototype, prop, {
enumerable: false,
value: function() {
return Object[prop](this);
}
});
}
console.log(obj);
console.log(obj.keys());
console.log(obj.values());
console.log(obj.entries());
You can edit the prototype methods, so that the change will be global.
Object.prototype.keys = function(){
return Object.keys(this);
}
Object.prototype.entries = function(){
return Object.entries(this);
}
Object.prototype.values = function(){
return Object.values(this);
}
const test = {
name: "bob"
};
console.log({
keys: test.keys(),
values: test.values(),
entries: test.entries(),
});