Proposal: Storage for getters and setters
Xavier MONTILLET
xavierm02.net at gmail.com
Fri Sep 30 07:14:41 PDT 2011
module name from "@name";
let key = name.create();
function MyClass(privateData) {
this[key] = privateData;
}
MyClass.prototype = {
doStuff: function() {
... this[key] ...
}
};
All it does is make the key a special string...
If you get the same string, you can still access the property...
Plus, either you make it non-enumerable so that noone can find the key
which is annoying, or you can find the key with a simple for in
loop...
I'm not sure I understand this proposal...
On Fri, Sep 30, 2011 at 3:55 PM, Dean Landolt <dean at deanlandolt.com> wrote:
>
>
> 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
More information about the es-discuss
mailing list