⬆️ ⬇️

Object.defineProperty or how to make code a bit better

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 handle may contain the following properties:



Example
Content

//    MDN var o = {}; Object.defineProperty(o, "a", {value : 37, writable : true, enumerable : true, configurable : true}); var bValue; Object.defineProperty(o, "b", {get : function(){ return bValue; }, set : function(newValue){ bValue = newValue; }, enumerable : true, configurable : true}); 




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 .

')

Example
Content

 //    MDN Object.defineProperties(obj, { "property1": { value: true, writable: true }, "property2": { value: "Hello", writable: false } // etc. etc. }); 






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 ); //  jQuery ,      }, each: function( callback ) { return $.each( this, callback ); //  } }); 




 o.extend({c: 3}); //       o.each(function( key, value ) { //    $.each,      }); 




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)

Source: https://habr.com/ru/post/150571/



All Articles