- The Book of Dojo
- Quick Installation
- Hello World
- Debugging Tutorial
- Introduction
- Part 1: Life With Dojo
- Part 2: Dijit
- Part 3: JavaScript With Dojo and Dijit
- Part 4: Testing, Tuning and Debugging
- Part 5: DojoX
- The Dojo Book, 0.4
Arrays and Objects as Member Variables
Submitted by david on Sun, 04/29/2007 - 14:31.
If your class contains arrays or other objects, they should be declared in the constructor so that each instance gets it's own copy. Simple types (literal strings and numbers) and are fine to declare in the class directly.
dojo.declare("my.classes.bar", my.classes.foo, {
someData: [1, 2, 3, 4], // doesn't do what I want: ends up being static
numItem : 5, // one per bar
strItem : "string", // one per bar
constructor: function() {
this.someData = [ ]; // better, each bar has it's own array
this.expensiveResource = new expensiveResource(); // one per bar
}
});
someData: [1, 2, 3, 4], // doesn't do what I want: ends up being static
numItem : 5, // one per bar
strItem : "string", // one per bar
constructor: function() {
this.someData = [ ]; // better, each bar has it's own array
this.expensiveResource = new expensiveResource(); // one per bar
}
});
On the other hand, if you want an object or array to be static (shared between all instances of my.classes.bar), then you should do something like this:
dojo.declare("my.classes.bar", my.classes.foo, {
constructor: function() {
dojo.debug("this is bar object # " + this.statics.counter++);
},
statics: { counter: 0, somethingElse: "hello" }
});
constructor: function() {
dojo.debug("this is bar object # " + this.statics.counter++);
},
statics: { counter: 0, somethingElse: "hello" }
});
"Statics" is not a special dojo construct - you can use any name you want, like "constants". In this example, you'd refer to the variable as myInstance.statics.counter both inside and outside the class definition.
Why is this true for arrays and objects, but not primitives? It's because, like most OOP languages, JavaScript uses object references. For example, given:
x = { fruit: "apple" };
y = x;
y = x;
Now x and y both refer to the same object. Modifying x.fruit will also affect y.fruit.
- Printer-friendly version
- Login or register to post comments
- Subscribe post
not really a static
You can only access the static members when you've got an instance, right? Or am I missing something?
You don't need an instance, actually
Let's not conjecture. Show it in code. It doesn't work.
<!-- Change directory as needed -->
<script type="text/javascript"
src="../dojo-release-1.0.0/dojo/dojo.js.uncompressed.js">
</script>
<script type="text/javascript">
dojo.declare("my.classes.foo",null,{});
dojo.declare("my.classes.bar", my.classes.foo, {
constructor: function() {
window.alert("this is bar object # " + this.statics.counter++);
},
statics: { counter: 0, somethingElse: "hello" }
});
// The following code does _not_ work as advertised!
// "my.classes.bar.statics has no properties"
// window.alert(my.classes.bar.statics.counter);
// This one does work
var bar=new my.classes.bar();
window.alert("Counter is "+bar.statics.counter);
</script>
</head>
<body>
Hello, world!
</body>
You should refer to the prototype of course..
try:
window.alert(my.classes.bar.prototype.statics.counter);
instead of:
window.alert(my.classes.bar.statics.counter);
Typo?
Is this a typo?
"On the other hand, if you want an object or array to be static (shared between all instances of my.classes.bar), then you should do something like this:"
Shouldn't it say...
"On the other hand, if you want a simply type variable like a string or number to be static (shared between all instances of my.classes.bar), then you should do something like this:"
Ambiguous
I think what is being said is closer to this: "In order to create a static primitive (simply typed) you need to "wrap' it in an object", Thus:
statics: { counter: 0, somethingElse: "hello" }
This tricks the engine into creating an object reference rather than by value. So the sentence makes sense as does your interpretation above.
It also seems to be true that unless you use the prototype you must have an instance of the class in order to access its static members. To compare this to Java the action of the prototype is the same as using the Class class.
If anyone believes the statements I have made here are incorrect please I beg you correct me. :-)
This is confusing.
I think we need to show examples of how this works...
field: [1,2,3,4], // static?
constructor: function() {
// Do nothing.
}
});
var a1 = new MyClassA();
var a2 = new MyClassA();
a1.field[0] = 5; // Changes values in both fields because a1 and a2 share the same field.
console.debug("a1.field = "+dojo.toJson(a1.field)); // prints [5,2,3,4]
console.debug("a2.field = "+dojo.toJson(a2.field)); // prints [5,2,3,4]
a1.field = [5,6,7,8]; // Replaces field in a1, but not in a2.
console.debug("a1.field = "+dojo.toJson(a1.field)); // prints [5,6,7,8]
console.debug("a2.field = "+dojo.toJson(a2.field)); // prints [5,2,3,4]
dojo.declare("MyClassB", null, {
field: {x:1, y:2}, // static?
constructor: function() {
// Do nothing.
}
});
var b1 = new MyClassB();
var b2 = new MyClassB();
b1.field.x = 3; // Changes values in both fields because b1 and b2 share the same field.
console.debug("b1.field = "+dojo.toJson(b1.field)); // prints {x:3,y:2}
console.debug("b2.field = "+dojo.toJson(b2.field)); // prints {x:3,y:2}
b1.field = {x:4, y:5}; // Replaces field in b1, but not in b2.
console.debug("b1.field = "+dojo.toJson(b1.field)); // prints {x:4,y:5}
console.debug("b2.field = "+dojo.toJson(b2.field)); // prints {x:3,y:2}
dojo.declare("MyClassC", null, {
field: {x:1, y:2}, // static?
constructor: function(args) {
dojo.mixin(this, args);
}
});
var c1 = new MyClassC({field:{x:3,y:4}});
var c2 = new MyClassC({field:{x:5,y:6}});
// When dojo.mixin() is used and field passed in args, field is no longer static
console.debug("c1.field = "+dojo.toJson(c1.field)); // prints {x:3,y:4}
console.debug("c2.field = "+dojo.toJson(c2.field)); // prints {x:5,y:6}