Proposal: Storage for getters and setters
Dean Landolt
dean at deanlandolt.com
Fri Sep 30 06:55:58 PDT 2011
On Fri, Sep 30, 2011 at 9:50 AM, Xavier MONTILLET
<xavierm02.net at gmail.com>wrote:
> 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?
>
See: http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110930/922aff3b/attachment-0001.html>
More information about the es-discuss
mailing list