...

View Full Version : Constructor problem with arrays?



Caffeine
07-16-2003, 10:29 AM
Hallo all,
I am trying to do my very first OOP- javascript and I am now stuck, why will this not work ?

function PP(width,height,oobjects,status,debug) {
this.width = width;
this.height = height;
this.steps = oobjects.length; // <<CAUSES THE ERROR
this.status = status;
this.debug = debug;
}

function callPP() {
var test = new PP();
test.width = 150;
test.height = 15;
test.steps = new Array("test1", "test2");
test.status = false;
test.debug = false;

document.write(test.steps);
}

I could do a 'dirty' workaround but I'd rather not, and I happen to be curious what's wrong with this code too :)

Thanks for any help.

ellisd5
07-16-2003, 10:34 AM
what are you passing into your function for 'oobjects'

Caffeine
07-16-2003, 10:38 AM
Usually it will be images in an array, but I'm thinking of maybe adding other files too, wav-files for example.

I'm trying to do a OO-progressbar, with some options, but I want to start out with a basic version first, then maybe add a few nice features.

thanks for your fast reply btw.

ellisd5
07-16-2003, 10:42 AM
So are you passing in the auctual whole Array, or just a single value. :confused:

If the codes not to big, post up the array and the part of the code that calls the function

Caffeine
07-16-2003, 10:46 AM
The whole array will be put on the bold line later on, I just used this to test around:

function callPP() {
var test = new PP();
test.width = 150;
test.height = 15;
test.steps = new Array("test1", "test2");
test.status = false;
test.debug = false;

document.write(test.steps);
}

cheesebagpipe
07-17-2003, 12:43 AM
Time to back up a bit and review some basics....

function callPP() {
var test = new PP();
.....

This calls your constructor PP(). It's just a function - albeit one with a specialized purpose - and it immediately executes the following statements:

this.width = width;
this.height = height;
this.steps = oobjects.length;

The first two run - in a poorly-conceived manner ('initializing' properties to 'undefined' rather than an actual value); but, since you've passed no oobjects object (array), you're asking the constructor to look up a property of 'undefined'. You'll need to either pass your constructor the necessary arguments to initialize the properties, or set 'placeholder' values (an empty array, in this case), or add some code that allows the constructor to analyze how it's being called, and set up accordingly. Try entering 'object-oriented JavaScript' in google, and click around for a while...;)

mordred
07-17-2003, 02:04 AM
Another tip if you want to improve your OO design a little: Use seperate methods to set/get the properties of your object. Those methods are (surprise, surprise!) conveniently refered to as getter and setter methods. They allow you to maintain and control the state of the object, and you can restrict the access to internal variables of the object.

If you combine that with the approach to make object variables private, you have a very good control of what the user of an object may alter and what not. Just some suggestions, ask for clarification if my post was to obscure. :D

Choopernickel
07-17-2003, 02:48 PM
Considering that there is no such thing as a true private or protected variable in javascript, OO design can only get so close before it's a waste of code.

Getters and setters are great for Java, smalltalk, coldfusion components, C++, any other kind of OO software or software tool which recognizes restrictions inside objects; in Javascript it's usually just as safe to name your "public" variables normally and prefix the "private" variables with an underscore or what-not.

Anything more is either practice for server-side or desktop applications, or programmatic masturbation.

mordred
07-17-2003, 09:45 PM
You can use closures to restrict the visibility of variables in an object:



function Obj() {
var foo = '';

this.setFoo = function(value) {
foo = value;
}

this.getFoo = function() {
return foo;
}
}

var test = new Obj();
test.setFoo('hello world');

alert(test.getFoo());
alert(test.foo); // <- Error: "foo is not defined"


Programmatic masturbation, eh? I'd say it's a rather useful concept. Just because it is not very common shouldn't mean that OOP principles should be softened when doing something more complex in JavaScript. But it's you choice, the nice thing in a language like JavaScript is that you can decide which route you take. YMMV.

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

Choopernickel
07-18-2003, 02:44 PM
Yet again, I find myself tasting shoe. Let me apologize for my flippant attitude, especially what with my admission that my knowledge of javascript really isn't up to par with my knowledge of my primary language (ColdFusion - please don't laugh at me).

Mordred, these revelations about javascript understanding private and protected properties and methods do make it feel more like java, but where does this leave room for the prototype, other than extending its methods? Should I create the properties in the constructor using var, then make getters and setters for each of them? Again, I feel this may be a waste of code, but it would be good to do at least for the variables which shouldn't be changed outside the object's methods, but do I then need getters and setters for each of these private vars, to be called inside the public methods?

So many questions, so many threads.

Danne
07-18-2003, 03:36 PM
Choopernickel:

It may seem like a waste of code using those getters and setters. But a good reason to do so is that they preserve the interface of the object. The only thing you need to worry about when using the object is to call it's methods. If the properties needs some formating or validation it's done inside the getters/setters.
Ex;



function foo(v){
var value;
this.setValue=function(v){
(isNaN(v) ? value = -1 : value = v);
}
this.getValue=function(){
(value==-1 ? return "N/A" : return value);
}
this.setValue(v);
}

// Usage:
var f=new foo(2);
var val=f.getValue();




Without them:




function foo(v){
this.value=(isNaN(v) ? -1 : v);
}

// Usage:
var f=new foo(2);
var val=f.value;
if (val==-1){
val = "N/A";
}


When you (or the client) later decides that it's should not be "N/A" but " - ", you have to look for all the places in your code where you used the value to change it.

Maybe a poor example, but you get the idea?

Choopernickel
07-18-2003, 04:10 PM
Okay, yeah, that makes sense Danne, so I understand why it makes sense to use setters and getters for a) variables that contain output data, and b) variables which have no need to be exposed.

What about setting variables, though? Imagine foo is an object, and bar is a switchable setting. Why bother with this:
function foo() {
// ...
var bar = false;
this.setBar = function (bool) {
bar = bool;
}
this.getBar = function () {
return bool;
}
}
foo.prototype.aMethod(splorp) {
if (this.getBar()) {
doSomething();
}
}
myFoo = new foo();
foo.setBar(true);
foo.aMethod();

when this will suffice
function foo() {
// ...
}
foo.prototype.bar = false;
foo.prototype.aMethod(splorp) {
if (this.bar) {
doSomething();
}
}
myFoo = new foo();
foo.bar = true;
foo.aMethod();
?

Why even bother with the prototype at all, when all of this can be coded with nested functions which access public and private variables all on their own? Is it really just a matter of style or personal preference? What kind of underlying benefits exist to the more OO approach of private variables and "priviledged" (not really protected) methods? Performance? Certainly not file size or code weight. Any?

So you know, I really do appreciate and am enjoying this conversation.

Danne
07-18-2003, 04:57 PM
Objectorientation may seem like more code in the beginning, but using it means reusable code, which means less coding. Once you have created the objects, all you need to do is use them. If you find a bug within an object, make sure the interface is intact.

When to use to use public properties and when not to? Avoid public properties when working with objects that you want to reuse.
This is probably a matter of choice, though. I know I use way too many public properties, and I usually have to suffer for it...:p

The downside of objectorientation may be performance and more time to plan the objects before the actual coding (which is actually a good thing, but may seem boring at first).

When you get in to inheritance (http://www.crockford.com/javascript/inheritance.html) is when you really start to love it..:D

Choopernickel
07-18-2003, 06:29 PM
That's the thing, though. I have a wonderful, pretty-much-OO script that is called via one line of instantiation code. It uses public properties and methods, and nothing private or priviledged. It weighs in at 142 lines of code (5.5kb), with nothing stored in the global scope except the constructor.

I went through and "privatized" it, making all the properties private and adding getters&setters, modifying all the code, etc. Its instantiation is the exact same, but now it weighs in at 204 lines (6.5kb), again with nothing stored in the global scope except the constructor. It works exactly the same in every way, except changing the settings.

I can't detect any changes in performance, but I haven't set up any timers or testers. I can't say whether it actually is better packaged, but it doesn't seem it. It's no more reusable with private variables than it is with public variables. The only difference I can see is that now I could create an API document, which would be beneficial to other developers. Documentation? Bah! ;)

However, it's time to post it in the "Post A Javascript" forum.

brothercake
07-18-2003, 06:55 PM
Encapsulation - if you're making an API for other people to use, there's a risk of variable and function-name conflicts when you don't know what else will be running. OO avoids that, because you only need one or a small number of container objects.

mordred
07-18-2003, 11:50 PM
Being aware of repeating what others have said already in this thread, let me respond why I think that getters/setters provide you with an advantage and are therefore a GoodThing(TM).

brothercake mentioned already encapsulation. You protect important innards of your object from unauthorized access. This allows you to change the internal structure of your private variable.

Say you have a config variable that's a string. But now, for some reasons only known to your PHB, this variable needs to be a random string from a list of strings everytime it is accessed. If you always accessed the variable directly, you need build a helper method that makes the random string and call that on every occasion you access the variable. If you'd have had a getter method, you could have called the randomizing method in your getter and you'd have to change the code at only one place. Reduces time-to-market and error probability.

Let's look at a setter. Going over a setter method to pass a value to the private variable allows you to detect malicous/wrong content as soon as possible. With a public variable, you could change the value everytime as you see fit. But then, maybe 1234 lines below, something screws up, and you get only the error message (if at all) from that line, and have to manually trace the flow of variables until you (eventually ;)) find the source of the error. A setter could have validated the input and thrown an exception if needed, you immediately know where something's going wrong.

It's interesting to see that in such a discussion always to counter-arguments pop up: Performance and bloat. Neither are really good arguments. If you're concerned about bloat, delete all whitespace in your script, that'll serve some bytes and protect your script mess from being copied (ok, ok, I'm too sarcastic here. :D Please don't take it personally, I mean it as a joke. :)). And of course, theoretically every layer of abstraction adds a fraction of performance loss to an application. But how great is this loss? Does it really matter? We're writing apps for web browsers, definitely rich clients. Not hardware drivers. I have yet to see a convincing benchmark that the impact of a getter method effects the performance of a script dramatically.
Well, I'm starting to ramble. Enough of that.

Perhaps it was not clear in my second post that I see private member variables as a useful concept, not as a mandatory concept. And for me that's one of the beauties of a script language like javascript, to have the choice which path I take. And it's nice to have some more paths to chose from. ;)

BTW, for me it's a nice discussion so far with interesting points debated. Let's see what can be added to it...

Choopernickel
07-21-2003, 04:43 PM
I think people may be under the impression that I'm not interested in OO javascript code - on the contrary, I quite am. I guess I'm worried about taking it too far, though I should really know better based on my experience using Fusebox: the main concern of people who've looked at Fusebox and not adopted it (nor understood it, in many cases) was that they were worried about trying to take it too far, or worried that somebody else would take it too far.

That said: I really like OO javascript. I've posted my OO type-ahead combo script (two versions) in the "Post a Javascript" forum, and am awaiting responses. My main question is this: How is it best to decide when a variable really needs to be private (only accessible via setters/getters) vs. public (contains an arbitrary value)? Did I just answer that myself?

Also, if there's going to be malicious/incorrect use by another developer, what's to stop that developer from modifying the OO code to begin with? If that happens, should I really concern myself with it?

Finally, what happens to the prototype? Is it really more effective or efficient not to add properties via prototype extension? Should prototypes only be extended with methods?

It's these finer points that I'm trying to get clear on inside my head.


Mordred, am I glad I'm not the only one enjoying this conversation.

Danne
07-21-2003, 08:28 PM
Private properties are useful:
- when you don't need it outside the object
- when you need to format or validate it before use

If you have a boolean, I doubt you need to make it private, unless its value depends on other values stored in the object too.
(if value is assigned 3 and the other value is 5 then value=true; else value=value; )
If it's another datatype still doesn't mean it has to be private. A property like "name" can probably be read and written to without any formatting.


If other developers have access to write to the object-files, they can of course modify them. But as long as they are only using them, they are forced to stick with the getters/setters.

I have no idea if it's better to use .prototype or not. I guess maybe it's a matter of taste. I normally use it for methods only.

beetle
07-21-2003, 09:24 PM
I only use prototyped inheritance for methods, as well.

I don't use private/protected members in my OO js for three reasons

1) My scripts are made such that a user would never need to use setters/getters themselves
2) KISS. Keep it Simple, Stupid. As someone said before - doing so requires more planning and thought, and I like to be lazy :D
3) If someone wants to mess around w/the properties - let 'em - just so long as they know they might break it!

I do, however, agree that they are a valuable concept and are in no way a wasted effort in JS.

Caffeine
07-22-2003, 08:48 AM
Thanks for all your replies, and plz don't stop! I enjoy it very much too, always nice to read a nice dialog with people knowing what they talk about :)

I have to put my JS-project on hold for a while, work has kept me way to busy the last couple of days.

The question I had (if anyone read it) is no longer a questionmark to me, I re-read the thread and that sorted it out.

Keep the posts coming, so far it has been a great read!



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum