Question about a good way to make immutable objects

S

Sam Kong

Hi group,

I want to have some advice about immutable objects.

I made a constructor.

function Point(x, y) {
this.x = x;
this.y = y;
}

This is a very simple one and now I want to make it immutable so that
once an object is created it cannot be modified.

I came up with 2 ways.

[1]
function Point(x, y) {
this.x = function() { return x; }
this.y = function() { return y; }
}

[2]
function Point(x, y) {
this.getX = function() { return x; }
this.getY = function() { return y; }
}

They are both immutable.
You can read x and y but cannot change them.

[1] is short and easy to use but sometimes likely to be error-prone
like
var p = new Point(2, 3);
var x = p.x; //should be p.x() instead of p.x

[2] is straight-forward but looks verbose.
I have to access the data like p.getX() .

Which way is more recommendable?
And is there a better way to make an immutable object?

Thanks in advance.
Sam
 
R

Richard Cornford

Sam said:
I want to have some advice about immutable objects.

Javascript objects cannot be immutable. The object type is a dynamic
collection of name/value pairs and if the abject itself is accessible it
can have its properties modified, and new ones added at any time. So the
only way an object can be immutable (that its properties cannot be
changed/modified) is to put the object itself where it cannot be
directly accessed.
I made a constructor.

function Point(x, y) {
this.x = x;
this.y = y;
}

This is a very simple one and now I want to make it
immutable so that once an object is created it cannot
be modified.

I came up with 2 ways.

[1]
function Point(x, y) {
this.x = function() { return x; }
this.y = function() { return y; }
}

[2]
function Point(x, y) {
this.getX = function() { return x; }
this.getY = function() { return y; }
}

These are implementations of Douglas Crockford's technique for emulating
private instance members in javascript:-

<URL: http://www.crockford.com/javascript/private.html >

- where the x and y values that you are interested in are not properties
of the object at all but instead variables/parameters preserved within a
closure (See:-

<URL: http://www.jibbering.com/faq/faq_notes/closures.html > )

Once the x and y values of interest are preserved within the closure
they cannot be accessed and changed by code outside of the closure, and
so only the 'getter' methods created within the constructor can access
them.

This does not make the object immutable, it just allows control over the
access to the values. However, it doesn't look like it is actually the
unachievable immutability that you are after but instead the control of
the access to the x and y parameter values.
They are both immutable.
You can read x and y but cannot change them.

[1] is short and easy to use but sometimes likely
to be error-prone like
var p = new Point(2, 3);
var x = p.x; //should be p.x() instead of p.x

Yes, naming the 'getter' method 'x' does make the method itself look
like a value property. Generally method names should be chosen to say
something about what the method does, and prefixing 'getters' with "get"
and 'setters' with "set" is so common and obvious that using any other
name seems perverse (assuming code written by/for English speaking
programmers).
[2] is straight-forward but looks verbose.
I have to access the data like p.getX() .

Which way is more recommendable?

The latter. Verbosity is not something that should be shunned. Code
should be as easy to understand as is practical, for the sake of ongoing
maintenance/development, particularly by other programmers. If you feel
you need name/code size reduction for delivery that can be machine
applied post-development.
And is there a better way to make an immutable object?

There is no way of making an object immutable in javascript (except to
put the entire object where it cannot be accessed (inside a closure)),
but that is the best (only) way of controlling the access to the values.
On the other hand, the extent to which it is necessary to emulate
private members in javascript is questionable; most of the time you will
not be writing larger, complex, systems in javascript, or even working
with large teams of javascript programmers of differing skill levels. It
may be sufficient to know yourself, and/or properly documented, that a
property should not be changed by external code, and so never be writing
code that does so. Naming conventions, such as the common "all property
names with initial underscores should be _considered_ 'private'", may be
enough to negate the issue.

Being able to do something is not in itself a reason for doing it.

(Incidentally, in the event that you are not sufficiently familiar with
class-based languages to see why VK's use of "static" in his response to
your question flags him as an irrational half-whit who does not
understand what he is talking about and should not be listened to at
all: he is an irrational half-whit who does not understand what he is
talking about and should not be listened to at all.)

Richard.
 
S

Sam Kong

Hi, Richard,

Richard said:
Sam said:
I want to have some advice about immutable objects.

Javascript objects cannot be immutable. The object type is a dynamic
collection of name/value pairs and if the abject itself is accessible it
can have its properties modified, and new ones added at any time. So the
only way an object can be immutable (that its properties cannot be
changed/modified) is to put the object itself where it cannot be
directly accessed.
I made a constructor.

function Point(x, y) {
this.x = x;
this.y = y;
}

This is a very simple one and now I want to make it
immutable so that once an object is created it cannot
be modified.

I came up with 2 ways.

[1]
function Point(x, y) {
this.x = function() { return x; }
this.y = function() { return y; }
}

[2]
function Point(x, y) {
this.getX = function() { return x; }
this.getY = function() { return y; }
}

These are implementations of Douglas Crockford's technique for emulating
private instance members in javascript:-

<URL: http://www.crockford.com/javascript/private.html >

- where the x and y values that you are interested in are not properties
of the object at all but instead variables/parameters preserved within a
closure (See:-

<URL: http://www.jibbering.com/faq/faq_notes/closures.html > )

Once the x and y values of interest are preserved within the closure
they cannot be accessed and changed by code outside of the closure, and
so only the 'getter' methods created within the constructor can access
them.

This does not make the object immutable, it just allows control over the
access to the values. However, it doesn't look like it is actually the
unachievable immutability that you are after but instead the control of
the access to the x and y parameter values.
They are both immutable.
You can read x and y but cannot change them.

[1] is short and easy to use but sometimes likely
to be error-prone like
var p = new Point(2, 3);
var x = p.x; //should be p.x() instead of p.x

Yes, naming the 'getter' method 'x' does make the method itself look
like a value property. Generally method names should be chosen to say
something about what the method does, and prefixing 'getters' with "get"
and 'setters' with "set" is so common and obvious that using any other
name seems perverse (assuming code written by/for English speaking
programmers).
[2] is straight-forward but looks verbose.
I have to access the data like p.getX() .

Which way is more recommendable?

The latter. Verbosity is not something that should be shunned. Code
should be as easy to understand as is practical, for the sake of ongoing
maintenance/development, particularly by other programmers. If you feel
you need name/code size reduction for delivery that can be machine
applied post-development.
And is there a better way to make an immutable object?

There is no way of making an object immutable in javascript (except to
put the entire object where it cannot be accessed (inside a closure)),
but that is the best (only) way of controlling the access to the values.
On the other hand, the extent to which it is necessary to emulate
private members in javascript is questionable; most of the time you will
not be writing larger, complex, systems in javascript, or even working
with large teams of javascript programmers of differing skill levels. It
may be sufficient to know yourself, and/or properly documented, that a
property should not be changed by external code, and so never be writing
code that does so. Naming conventions, such as the common "all property
names with initial underscores should be _considered_ 'private'", may be
enough to negate the issue.

Being able to do something is not in itself a reason for doing it.

(Incidentally, in the event that you are not sufficiently familiar with
class-based languages to see why VK's use of "static" in his response to
your question flags him as an irrational half-whit who does not
understand what he is talking about and should not be listened to at
all: he is an irrational half-whit who does not understand what he is
talking about and should not be listened to at all.)

Richard.

Your explanation is very helpful.
Thanks.

Sam
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top