By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,238 Members | 1,152 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,238 IT Pros & Developers. It's quick & easy.

Object-arrays - duplicate object-references

P: n/a
Hi, I've stumbled into a problem I just can't figure out. I found out
that variables in JS don't have local scope inside brackets in say, a
loop, but things still doesn't add up. Also, the phenomena seemed very
much alike to a closure-related one, but I'm not returning any
functions as far as I can see (I'm fresh when it comes to closures
tho). Let me illustrate the very basic task at hand, which is filling
an array with new objects. All seven positions in the array returned
point to the same object!

---code---

var o = new Array();

for(var j=0; j<7; j++) {

//Create object
var obj = new SomeType();

//Manipulate object
obj.doSomething();
o[j] = obj;

}

//Array not what is expected here

someOtherObj.setArray(o);

---/code---
I also tried the code below to no avail. I don't see how it's any
different.
---code---

var o = new Array();

for(var j=0; j<7; j++) {

//Create object
o[j] = new SomeType();

//Manipulate object
o[j].doSomething();

}

//Array not what is expected here

someOtherObj.setArray(o);

---/code---

Does anyone have any enlightening explanations for why this occurs,
and what a solution might be?

Thanks
Jun 27 '08 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Are Nybakk wrote:
[...] Let me illustrate the very basic task at hand, which is filling
an array with new objects. All seven positions in the array returned
point to the same object!
No, they don't.
---code---
function SomeType(bar)
{
this.foo = bar;
}

SomeType.prototype = {
constructor: SomeType,
doSomething: function() {}
};
var o = new Array();

for(var j=0; j<7; j++) {

//Create object
var obj = new SomeType();
For proof, replace with this line with

var obj = new SomeType(j);
//Manipulate object
obj.doSomething();
o[j] = obj;

}

//Array not what is expected here
You have not said what you expect. Anyhow:

// 0,1
window.alert([o[0].foo, o[1].foo]);
someOtherObj.setArray(o);
The error may lie in here.
Does anyone have any enlightening explanations for why this occurs,
and what a solution might be?
Maybe if you posted the code of SomeType() or someOtherObj.setArray().

http://www.jibbering.com/faq/faq_not...ml#ps1DontWork
PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Jun 27 '08 #2

P: n/a
On Apr 12, 11:31 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Are Nybakk wrote:
[...] Let me illustrate the very basic task at hand, which is filling
an array with new objects. All seven positions in the array returned
point to the same object!

No, they don't.
If so, they are all identical objects, which is not the case. The
objects are created correctly, I have confirmed it.

*snip*
//Array not what is expected here

You have not said what you expect. Anyhow:
An array of 7 different objects?
>
// 0,1
window.alert([o[0].foo, o[1].foo]);
someOtherObj.setArray(o);

The error may lie in here.
This was just to illustrate what it's beeing used for later. The array
is wrong before this call.
>
Does anyone have any enlightening explanations for why this occurs,
and what a solution might be?

Maybe if you posted the code of SomeType() or someOtherObj.setArray().
Simplified:

function SomeType() {

//private variables
var m_id = 0;

SomeType.prototype.setId = function(id) {
m_id = id;
}

SomeType.prototype.getId = function() {
return m_id;
}

}

Is it correct to set the methods inside the class like this btw? I
tested it and creating objects worked. Is it possible that all objects
of this type somehow operate on the same "private" variables?

*snip*

Jun 27 '08 #3

P: n/a
*snip*
Maybe if you posted the code of SomeType() or someOtherObj.setArray().

Simplified:

function SomeType() {

//private variables
var m_id = 0;

SomeType.prototype.setId = function(id) {
m_id = id;
}

SomeType.prototype.getId = function() {
return m_id;
}

}

Is it correct to set the methods inside the class like this btw? I
tested it and creating objects worked. Is it possible that all objects
of this type somehow operate on the same "private" variables?
I think I was into something here. It seems the code below works as it
was meant to be :)

function SomeType() {

//private variables
var m_id = 0;

}

SomeType.prototype.setId = function(id) {
this.m_id = id;
}

SomeType.prototype.getId = function() {
return this.m_id;
}
Jun 27 '08 #4

P: n/a
Are Nybakk wrote:
[...] Thomas 'PointedEars' Lahn [...] wrote:
>Are Nybakk wrote:
>>[...] Let me illustrate the very basic task at hand, which is filling
an array with new objects. All seven positions in the array returned
point to the same object!
No, they don't.

If so, they are all identical objects,
Pardon? You have said that they point to (refer to) the same object, my
test case shows that they do not. If what I said (and what my test case
proves) is true, there are different objects, of course.
which is not the case.
Of course not.
The objects are created correctly, I have confirmed it.
Doesn't matter.
*snip*
>>//Array not what is expected here
You have not said what you expect. Anyhow:

An array of 7 different objects?
Which is what happens. Have you even bothered to run my test case?
> // 0,1
window.alert([o[0].foo, o[1].foo]);
>>someOtherObj.setArray(o);
The error may lie in here.

This was just to illustrate what it's beeing used for later. The array
is wrong before this call.
Then the error may lie only in the constructor, obj.doSomething(), or the
way you instantiate your variables.
>>Does anyone have any enlightening explanations for why this occurs,
and what a solution might be?
Maybe if you posted the code of SomeType() or someOtherObj.setArray().

Simplified:

function SomeType() {

//private variables
var m_id = 0;

SomeType.prototype.setId = function(id) {
m_id = id;
}

SomeType.prototype.getId = function() {
return m_id;
}
}

Is it correct to set the methods inside the class like this btw?
Firstly, there are no classes, these are languages that provide
prototype-based inheritance:

http://javascript.crockford.com/javascript.html
http://javascript.crockford.com/inheritance.html

It is correct, however less efficient than one-time redefinition/
augmentation, to try augmenting/redefining the prototype object in the
constructor.
I tested it and creating objects worked. Is it possible that all objects
of this type somehow operate on the same "private" variables?
Nevertheless, with such an initialization you do create a closure, with
`m_id' being a variable bound to the local execution context of the
constructor, and so the methods do operate on the same local variable
instantiated on the last constructor call (since that is when you define
the prototype methods last).

Here is a way to create private members that works as supposed:

function SomeType()
{
// private member
var m_id = 0;

this.setId = function(id) {
m_id = id;
};

this.getId = function() {
return m_id;
};
}

As you can see, in current client-side ECMAScript implementations you can
only buy information hiding with decreased memory efficiency.

http://www.crockford.com/javascript/private.html
HTH

PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Jun 27 '08 #5

P: n/a
Are Nybakk wrote:
*snip*
>>Maybe if you posted the code of SomeType() or someOtherObj.setArray().
Simplified:

function SomeType() {
//private variables
var m_id = 0;

SomeType.prototype.setId = function(id) {
m_id = id;
}

SomeType.prototype.getId = function() {
return m_id;
}
}

Is it correct to set the methods inside the class like this btw? I
tested it and creating objects worked. Is it possible that all objects
of this type somehow operate on the same "private" variables?

I think I was into something here. It seems the code below works as it
was meant to be :)
Only that you have no information hiding anymore, and that the local
variable really has become superfluous as it is _not_ used:
function SomeType() {

//private variables
var m_id = 0;
Unused local variable.
}

SomeType.prototype.setId = function(id) {
this.m_id = id;
Creates a new property of the calling object named `m_id', value of `id', or
overwrites the value of the existing property with that name.
}

SomeType.prototype.getId = function() {
return this.m_id;
Returns the value of the property named `m_id' of the calling object, or
`undefined' if the property has not been defined or set to `undefined' before.
}
And so

var o = new SomeType();
o.m_id = 'x';
window.alert(o.m_id);

is possible again. Not quite what you wanted, is it?
PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>
Jun 27 '08 #6

P: n/a
Thomas 'PointedEars' Lahn wrote:
Are Nybakk wrote:
>SomeType.prototype.getId = function() {
return this.m_id;

Returns the value of the property named `m_id' of the calling object, or
`undefined' if the property has not been defined or set to `undefined' before.
>}

And so

var o = new SomeType();
o.m_id = 'x';
window.alert(o.m_id);

is possible again. Not quite what you wanted, is it?
For a better proof that nothing is private anymore then, use

var o = new SomeType();
o.m_id = 'x';
window.alert(o.getId());

or

var o = new SomeType();
o.setId('x');
window.alert(o.m_id);
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Jun 27 '08 #7

P: n/a
*snip*
Maybe if you posted the code of SomeType() or someOtherObj.setArray().

Simplified:

function SomeType() {

//private variables
var m_id = 0;

SomeType.prototype.setId = function(id) {
m_id = id;
}

SomeType.prototype.getId = function() {
return m_id;
}

}

Is it correct to set the methods inside the class like this btw? I
tested it and creating objects worked. Is it possible that all objects
of this type somehow operate on the same "private" variables?
I think I was into something here. It seems the code below works as it
was meant to be :)

function SomeType() {

//private variables
var m_id = 0;

}

SomeType.prototype.setId = function(id) {
this.m_id = id;
}

SomeType.prototype.getId = function() {
return this.m_id;
}
Jun 27 '08 #8

P: n/a
On Apr 12, 12:48 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Thomas 'PointedEars' Lahn wrote:
Are Nybakk wrote:
SomeType.prototype.getId = function() {
return this.m_id;
Returns the value of the property named `m_id' of the calling object, or
`undefined' if the property has not been defined or set to `undefined' before.
Yes, I bumped into this as I had set properties on some of those
variables in the constructor. The methods did then not know of it,
giving 'undefined' results.
>
}
And so
var o = new SomeType();
o.m_id = 'x';
window.alert(o.m_id);
is possible again. Not quite what you wanted, is it?

For a better proof that nothing is private anymore then, use

var o = new SomeType();
o.m_id = 'x';
window.alert(o.getId());

or

var o = new SomeType();
o.setId('x');
window.alert(o.m_id);
I think I'm beginning to hate JS :p Thanks for clearing this up.

I wonder which is generally the better of two evils.. inefficient data-
hiding or efficient public data... any thoughts? Some of my classes
contain only "static" methods, so there's no problem there, but I have
some others which contains data, like in this example, and just 1-2
methods. I wouldn't say the data-hiding is _necessary_, but in some
cases value-checking might be nice to have. The code certainly would
be more robust and reusable that way. I guess I'm pretty much
answering my own question.
>
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Jun 27 '08 #9

P: n/a
Are Nybakk wrote:
[...] Thomas 'PointedEars' Lahn [...] wrote:
>For a better proof that nothing is private anymore then, use

var o = new SomeType();
o.m_id = 'x';
window.alert(o.getId());

or

var o = new SomeType();
o.setId('x');
window.alert(o.m_id);

I think I'm beginning to hate JS :p Thanks for clearing this up.

I wonder which is generally the better of two evils.. inefficient data-
hiding or efficient public data... any thoughts? Some of my classes
contain only "static" methods, so there's no problem there, but I have
some others which contains data, like in this example, and just 1-2
methods. I wouldn't say the data-hiding is _necessary_, but in some
cases value-checking might be nice to have. The code certainly would
be more robust and reusable that way. I guess I'm pretty much
answering my own question.
Yes, why not use the best of both worlds? It appears to reasonable to use
private members and protected accessor methods only when information hiding
or value checking is required, and public properties otherwise.

However, to ease your pain a little bit ;-) there are ECMAScript
implementations that support getters and setters. For example,
JavaScript 1.5:

function SomeType()
{
var id = 0;

this.__defineGetter__(
"id",
function() {
return id;
}
);

this.__defineSetter__(
"id",
function(v) {
if (!isNaN(v)) id = v;
}
);
}

var o = new SomeType();

o.id = "a";

// 0
window.alert(o.id);
Please trim your quotes to the necessary minimum.
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Jun 27 '08 #10

P: n/a
Are Nybakk <ne**@arenybakk.comwrites:
I think I was into something here. It seems the code below works as it
was meant to be :)
Almost.
function SomeType() {

//private variables
var m_id = 0;
This declares a local variable that is not accessible by any other
code. You can remove the declaration and not change anything.

You might vant to do:
this.m_id = 0;
instead, which does initialize the object property that the following
methods access:
SomeType.prototype.setId = function(id) {
this.m_id = id;
}
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jun 27 '08 #11

P: n/a
*snip*
However, to ease your pain a little bit ;-) there are ECMAScript
implementations that support getters and setters. For example,
JavaScript 1.5:
*snip*

Ah, now that's very nice! Too bad it seems IE doesn't support this.
Personally I don't see any point at all in using IE, but the users do,
sadly. Thanks again for the input, it was really useful 8)

(Sigh, I need to go back to a real usenet-client. Damn Google...)
Jun 27 '08 #12

This discussion thread is closed

Replies have been disabled for this discussion.