The limitations of object-oriented JavaScript can really make web development difficult. Today I was refactoring some newly-written code and was surprised to find my page had broken because this was evaluating to an unexpected value.
Here’s what the code looked like:
function SampleObject(value)
{
this.value = Number(value);
this.Increment = PrivateIncrement;
this.getValue = function() { return this.value; }
function PrivateIncrement() {
this.value++;
}
/* try to automatically increment number
* when instantiated; (will fail because
* "this" will equal "window")
*/
PrivateIncrement();
}
/* displays 10; number not incremented */
var myObj = new SampleObject(10);
window.alert(myObj.getValue());
/* displays 11; increments as expected */
myObj.Increment();
window.alert(myObj.getValue());
When I looked at the PrivateIncrement function more closely, I noticed that this was evaluating to the window object when SampleObject was being instantiated. However, it was evaluating to myObj when myObj.Increment was called. I could work around it by:
/* calling PublicIncrement directly */ this.Increment(); /* using the "call" syntax */ PrivateIncrement.call(this);
I then remembered a workaround that I had seen before but that I hadn’t bothered to understand:
function SampleObject(value)
{
var self = this;
...
function PrivateIncrement() {
self.value++;
}
...
}
Yech. All this finally makes sense at the technical level, but…why can’t you just let me call PrivateIncrement directly?
If the gurus tell me I can write object-oriented JavaScript, why are articles about object-oriented JavaScript always about technique, not design? Why is it that I have to force basic tenets of object-oriented programming into JavaScript’s primitive worldview?
Why does JavaScript have to make web development so difficult sometimes?
Shouldn’t value be a private member (”var value” instead of “this.value”)?
And if PrivateIncrement() is “private”, why not use “var PrivateIncrement = function () …”? The original code works as expected if value is private.
Comment by ME [Visitor] — September 27, 2005 @ 10:47 am
ME, thanks for your feedback.
First of all, let me point out that in a private function such as you described, “this” will equal the function object:
var PrivateIncrement = function() {
/* this == PrivateIncrement */
};
Strictly for the purposes of solving this problem, I can’t see any advantage to defining the function like this. (That doesn’t mean isn’t not advantageous in other situations!) Correct me if I’m wrong.
Second, you’re right that the example could be improved. Admittedly it would make more sense to have “value” be a private member, publicly accessible through the getter function getValue.
However, I think the pattern still applies. There are times when it would be nice to have a private function call a public function.
I now think the best solution is making such functions be both public and private.
In this case, that means making “value” private and writing public getter/setter functions, which is what you suggested.
Thoughts?
Comment by Matthias Miller [Member] — September 27, 2005 @ 11:31 am
Uhh. I wish with all my heart I knew what you just said. I know… uhh… nothing about codes, except that I once wrote prototype for data flow software. I learned a few things about “tell” and “if”, and I got addicted. Now, I want to know about C language, and I have no Idea where to start. I don’t want to spend any money, and I thought maybe you’d have a clue how I should start. Wanna help? I saw your blog thru Hans’, he’s a friend of mine. Oh, if it makes a difference, I’m using a Macintosh, not Windows.
Here’s my quote of the day:
“And the Gates of hell shall not prevail against me. My Job[s] is quite safe.”
Comment by Nic Miller [Visitor] — October 10, 2005 @ 7:25 pm
To get started, you will need to install a compiler on your computer. This is also sometimes referred to as an Integrated Development Environment, or IDE. I’m not very familiar with what’s available for the Mac, but with a little searching I found:
-Xcode, which requires an Apple ID to download. Looks like a pretty good solution; if I’d have a Mac, I’d probably try this first.
-The Macintosh Programmer’s Workshop–I’m not sure what all this package offers.
-Metrowerk’s CodeWarrior for the Mac–somewhat pricey for a hobbyist (don’t know if you qualify for the academic version). I expect it to be fairly good software.
To learn more about the language, you might try out with the C tutorial. Also, we’ve got a book at the office that provides a good start, but it’s borrowed out right now, and I can’t come up with the title. I’ll see if I can come up with the name and author of the book.
Comment by Matthias Miller [Member] — October 11, 2005 @ 11:22 am
I finally found the book I was looking for: Teach Yourself C. The Second Edition is somewhat older but should be just as relevant (that’s the copy that I’ve got). I think this book should be very helpful in getting started in learning how to program in C.
Comment by Matthias Miller [Member] — October 14, 2005 @ 12:19 pm
[...] Filed under: JavaScript — outofhanwell @ 4:58 am Several months ago I complained about the limitations of object-oriented JavaScript. I’ve changed my [...]
Pingback by Object-Oriented JavaScript « Out of Hanwell — September 20, 2007 @ 10:12 pm