I bring to your attention a translation of the article " Advanced Javascript Properties " from jstips.co.
You can configure objects in javascript so that, for example, they can set the properties to be pseudo-private or readonly. This feature is available starting from ECMAScript 5.1, therefore it is supported by all browsers of the latest versions. To do this, you need to use the
defineProperty method for an
Object , like this:
var a = {}; Object.defineProperty(a, 'readonly', { value: 15, writable: false }); a.readonly = 20; console.log(a.readonly);
The syntax is:
Object.defineProperty(dest, propName, options)
Or for several properties:
')
Object.defineProperties(dest, { propA: optionsA, propB: optionsB,
Where
options includes the following attributes:
value - if it is not getter (see below), then value is a required attribute.
{a: 12} === Object.defineProperty (obj, 'a', {value: 12})
writable - sets the property to readonly. Note that if a property is nested, then it is editable.
enumerable - sets the property as hidden. This means that for ... of and stringify will not issue it in its result, although it still exists. Note. This does not mean that the property becomes private. It is still accessible from the inside, just will not be displayed.
configurable - sets the property as not changeable, for example, protected from deletion or predetermination. Again, if the property is nested, then it can be edited.
So in order to create a private persistent property, you must define it as:
Object.defineProperty(obj, 'myPrivateProp', {value: val, enumerable: false, writable: false, configurable: false});
In addition to setting properties,
defineProperty can define them dynamically, thanks to the second parameter, which is a string. For example, suppose I want to create properties according to some configuration:
var obj = { getTypeFromExternal(): true
But that's not all! Additional properties allow you to create getters and setters, like other OOP languages. However, in this case you cannot use
writable, enumerable and
configurable.
function Foobar () { var _foo;
Except for the cases of obvious advantages of encapsulation and extended accessors, you can see that we do not “call” the getter, but get it as a property, without brackets! This is amazing! For example, let's imagine that we have an object with a bunch of nested properties:
var obj = {a: {b: {c: [{d: 10}, {d: 20}] } } };
Now, instead of abc [0] .d (where one of the properties may turn out to be undefined and throw an error), we can create an alias:
Object.defineProperty(obj, 'firstD', { get: function () { return a && ab && abc && abc[0] && abc[0].d } }) console.log(obj.firstD)
Comment
If you try to install a getter without a setter and try to set a value, you will get an error. This is especially important when using helper functions such as $ .extend or _.merge. Be careful!
Links