Hi, I've been playing with getters and setters for a little while and there's one thing really bothering me: You can't store the value in the object in a hidden way. Here is an example:
http://jsfiddle.net/xavierm02/UzNK3/13/ function Point( x, y ) { this.x = x; this.y = y; } Object.defineProperties( Point.prototype, { x: { get: function ( ) { // this would return the stored value }, set: function ( value ) { value = parseInt( value ); // and here, you would want to set "this.x" to value but you can't since this would create an infinite loop } }, y: { // same here } } ); You could do it by: - using Object.defineProperties in the constructor and therefore but then, you would have several times the same function created so it kinda sucks. http://jsfiddle.net/xavierm02/UzNK3/14/ function Point( x, y ) { Object.defineProperties( Point.prototype, { x: { get: function ( ) { return x; }, set: function ( value ) { x = parseInt( value, 10 ); } }, y: { // same here } } ); } - have some kind of array where you store values and another array where you store the this and let those arrays be accessible only from the methods needing it. Then you would get the index of the instance by doing indexOf( this ) on the array of instances and then you would search for the value at this index. Sucks too. http://jsfiddle.net/xavierm02/UzNK3/15/ ( function ( ) { var instances = [ ], xs = [ ], ys = [ ]; function Point( x, y ) { instances.push( this ); xs.push( x ); ys.push( y ); } Object.defineProperties( Point.prototype, { x: { get: function ( ) { return xs[ instances.indexOf( this ) ]; }, set: function ( value ) { xs[ instances.indexOf( this ) ] = parseInt( value ); } }, y: { // same here } } ); this.Point = Point; } )( ); I don't know know what you think of this but these methods really aren't convenient from my point of view... There are potential new features that could allow you to do this too: - private properties but then that would mean giving access to private properties to the methods in the prototype, which would mean that adding a method in the prototype would allow to change the values, which isn't what you want... Even though you could freeze the prototype to avoid it... - I remember thinking of another one but I can't remember which one atm... So here'swhat I propose: - the getter gets a parameter which is the stored value - the setter's return value is set as value for the "private" property Here's an implementation of what I would like having (It sucks sinces it prevents garbage collecting and could easilly be optimized but still works): http://jsfiddle.net/xavierm02/UzNK3/17/ Object.defineProperties = ( function ( ) { var defineProperties = Object.defineProperties; return function ( object, propertyDescriptors ) { for ( var name in propertyDescriptors ) { if ( propertyDescriptors.hasOwnProperty( name ) ) { ( function ( propertyDescriptor ) { var get; var set; if ( propertyDescriptor.hasOwnProperty( 'get' ) ) { get = propertyDescriptor.get; propertyDescriptor.get = function ( ) { return get.call( this, propertyDescriptor.value ); }; } if ( propertyDescriptor.hasOwnProperty( 'set' ) ) { set = propertyDescriptor.set; propertyDescriptor.set = function ( value ) { return propertyDescriptor.value = set.call( this, value ); }; } } )( propertyDescriptors[ name ] ); } } defineProperties( object, propertyDescriptors ); }; } )( ); And you would use it that way: http://jsfiddle.net/xavierm02/UzNK3/17/ function Point( x, y ) { this.x = x; this.y = y; } Object.defineProperties( Point.prototype, { x: { get: function ( value ) { return value; }, set: function ( value ) { value = parseInt( value ); return value; } }, y: { // same here } } ); Of course, if it were implemented, it would probably allow setting a defaut setter that woudl simply assign and a a default getter that would simply return the value by putting true instead of the function. Or somthing similar. Of course, for this example, implementing type checking would make it useless. But that really was just a example. Something where it would have a real use is, for example: http://jsfiddle.net/xavierm02/UzNK3/20/ // isn't suposed to work // here just for wyntax coloration function WYSIWYGEditor( ) { Object.defineProperties( this, { iframe: { value: document.createElement( 'iframe' ), configurable: false, enumerable: true, writable: false }, textarea: { value: document.createElement( 'textarea' ), configurable: false, enumerable: true, writable: false }, container: { value: document.createElement( 'div' ), configurable: false, enumerable: true, writable: false } } ); Object.defineProperty( this, 'wysiwygField', { value: this.iframe./* get the container */, configurable: false, enumerable: true, writable: false } ) this.container.appendChild( iframe ); } Object.defineProperties( WYSIWYGEditor.prototype, { wysiwyg: { value: true, configurable: false, enumerable: true, get: function ( value ) {// or simply true or somethign similar is shorcuts are implemented return value }, set: function ( value ) { value = !!value; if ( value ) { this.wysiwygField.innerHTML = this.textarea.value; this.container.removeChild( this.textarea ); this.container.appendChild( this.iframe ); } else { this.textarea.value = this.wysiwygField.innerHTML; this.container.removeChild( this.iframe ); this.container.appendChild( this.textarea ); } return value; } } } ); What do you think? _______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

