This brief post-note
or temperature nonsense (in Odessa it got
colder, yes) I want to devote to such an excellent function as Object.defineProperty (and Object.defineProperties). I have been actively using it for about two months, since the support of old browsers (including IE8) in the project that I am implementing now is not required (envy).
As expected article on Habré, I will give a brief description of what she does. Object.defineProperty adds a new property with some non-standard behavior for a normal property and takes three arguments:
- The object we are modifying by adding a new property
- Property (string), which, in fact, we want to add
- Descriptor: an object containing the “settings” of a new property, for example, processors (getter, setter)
The handle may contain the following properties:
- value (any value: string, function ...) - the value that the determined property of the object will receive (getter and setter cannot be determined in this case)
- writable (true / false) - is it possible to overwrite the value of a property (processors are also not available)
- get (function) - getter (value and writable cannot be defined)
- set (function) - setter (value and writable cannot be defined)
- configurable (true / false) - is it possible to redefine a descriptor (use Object.defineProperty over the same property)
- enumerable (true / false) - whether the property will be listed through for..in and is available in Object.keys (poor wording)
MDN
Object / defineProperty will explain me better. Fortunately, even the English do not need to know, and so everything is clear.
If you need to define several properties at once, you can use Object.defineProperties, which takes two arguments: an object that needs to be changed and an object with defined keys.
MDN:
Object / defineProperties .
')
Now salt. Why did I even decide to post it?
Since in the project mentioned above I have to use defineProperty not just actively, but very actively, the code has become, to put it mildly, ugly. I came up with the simplest idea (how did I not think of it before?), To extend the Object prototype, making the code much more compact. Bad tone, you say, to zerit Object prototype with new methods.
Where did this opinion come from? Because all objects will inherit this property, which, with the usual modification of the prototype, becomes enumerated in for..in. It becomes warm to the soul when you remember what I described above, namely, the enumerable property of the descriptor. Indeed, expanding the prototype in this way:
Object.defineProperty( Object.prototype, 'logOk' { value: function() { console.log('ok') }, enumerable: false });
all objects will receive this method, but at the same time, it will be non-enumerable (you do not need to use hasOwnProperty every time to check if there is such a property):
var o = {a: 1, b: 2} for( var i in o ) console.log( i, o[ i ] ); > a 1 > b 2 o.logOk(); > ok
Actually, for the sake of what I'm here graphomaniac.
First, we define a define method, so that each time we don’t call an overloaded, in my opinion, construction. Secondly, we define the extendNotEnum method, which extends an object with non-enumerable properties.
Object.defineProperties( Object.prototype, { define: { value: function( key, descriptor ) { if( descriptor ) { Object.defineProperty( this, key, descriptor ); } else { Object.defineProperties( this, key ); } return this; }, enumerable: false }, extendNotEnum: { value: function( key, property ) { if( property ) { this.define( key, { value: property, enumerable: false, configurable: true }); } else { for( var prop in key ) if( key.hasOwnProperty( prop ) ){ this.extendNotEnum( prop, key[ prop ] ); } } }, enumerable: false } });
Using:
var o = { a: 1 }; o.define( 'randomInt', { get: function() { return 42; } }); o.extendNotEnum({ b: 2; }); for( var i in o ) console.log( i, o[ i ] ); > a 1 > randomInt 42 console.log( ob ); > 2
And she went ... Two more convenient methods:
Object.prototype.extendNotEnum({ extend: function() { var args = Array.prototype.slice.call( arguments ); args.unshift( this ); return $.extend.apply( null, args );
o.extend({c: 3});
You can add new properties to infinity, no one will bite your hand off for this.
Conclusion
Play Dandy, write to Javascript, which is getting better and better.
(If you notice a typo or inaccuracy, please contact the PM)