What I essentially want to do is this:
Blog.prototype = {
set content(content) {
this.content = JSON.parse(content);
}
}
However, this results in infinite recursion.
I know I can do something like:
set content(content) {
this._content = JSON.parse(content);
},
get content() {
return this._content;
}
However, when I do JSON.stringify(blog)
, it doesn't include content
, but includes _content
, which is undesirable.
How can I go about doing this?
Make the "_content" variable non-enumerable.
Blog.prototype = {
set content(newContent) {
Object.defineProperty(this, "_content", {
value: JSON.parse(newContent),
writable: true
});
},
get content() {
return this._content;
}
};
By default, an the "enumerable" flag for an object property is false
if not supplied explicitly in the call to defineProperty()
.
Someday the Symbol type will be universally supported, and it'd be a better choice for this because you can make a guaranteed unique property key that way. If you don't need IE support and can use Symbols:
Blog.prototype = () => {
const internalContent = Symbol("content key");
return {
set content(newContent) {
this[internalContent] = newContent;
},
get content() {
return this[internalContent];
}
};
}();
Symbol-keyed properties are ignored by JSON.stringify()
so you don't have to bother with defineProperty()
. The nice thing about the Symbol approach is that you don't have to worry about collisions. Every Symbol instance returned from Symbol()
is distinct.
Use Set and Get with _content
, and implement .toJson()
to provide JSON.stringify
with content
instead of _content
.
toJSON() {
return {
content: this._content
}
}
According to MDN .toJSON()
role is:
If an object being stringified has a property named toJSON whose value is a function, then the toJSON() method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON() method when called will be serialized.
Using with a constructor function
function Blog() {}
Blog.prototype = {
set content(content) {
this._content = JSON.parse(content);
},
get content() {
return this._content;
},
toJSON() {
return {
content: this._content
}
}
};
var blog = new Blog();
blog.content = '{ "a": "5" }';
console.log(blog.content);
console.log(JSON.stringify(blog));
Using with ES6 class
class Blog {
set content(content) {
this._content = JSON.parse(content);
}
get content() {
return this._content;
}
toJSON() {
return {
content: this._content
}
}
};
const blog = new Blog();
blog.content = '{ "a": "5" }';
console.log(blog.content);
console.log(JSON.stringify(blog));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With