views:

99

answers:

3

I'm starting out with classes in Javascript and have hit a wall. I've looked all over for a tutorial that goes a little further than simply how to construct a class (usually Animal) then extend the class and have a Method do something (Dog alert('Bark');).

I have created a class that I want a user to be able to instantiate (is that the right word)? For example the first stage in my program is for the user to give the class a name, and then start to populate the various variables in the class. When they've done that they may do it again many times.

EDITED, FULL EXAMPLE OF CODE:

function Blind() {
    this.Type = null;
    this.Colour = null;
    this.Width = 500;
    this.Drop = 500;
    this.Price = 0;
}

function BlindAluminium() {
    Blind.call(this);
    this.Type = 'aluminium';
    this.SubType = null;
    this.StackHeight = 0;
}

That is the code that defines the object.

Here is the HTML that will allow the user to define a new object:

<form id="create_blind_form" name="create_blind_form" method="post" action="">
    <label for="blind_name">Blind Name: <input name="blind_name" id="blind_name" type="text" /></label>
    <input name="submit" type="submit" value="Submit" />
</form>

On submitting that I need a new object to be created, in pseudo-code, something like this:

var *blind_name_from_the_form* = new BlindAluminium();

Then later I hope to act on it like this:

*blind_name_from_the_form*.subType = '50mm';
+5  A: 

The short answer is that you're going to have to use eval. If you want to call a function (or class) with a name known only at run-time, there's no way around it.

eval("var className = new MyObject();");

That being said, you may want to consider some alternatives. People will give you all sorts of reasons why eval is bad, which are true. But to me, going down this route is just going to be awkward to manage. Yes, dig into Crockford.

Is it possible to use Javascript's prototypical inheritance, instead of trying to use awkward classes? Given that classes mean nothing in Javascript, there's really no reason to use them if they don't fit the problem.

ndp
Surely that can't be true. How about: `function a() { return 'foo' } this['a']()`? Evaluates in my Google Chrome console to "foo," as expected. But I also am still having difficulty understanding what the original question is asking, so...
Matchu
@Matchu: Your function call in a string might count as 'awkward' or bad usage even if you're not also using `eval`; however I understand you're refuting the assertion eval is needed - great example for that.
John K
+1 for "Given that classes mean nothing in Javascript, there's really no reason to use them if they don't fit the problem there's really no reason to use them if they don't fit the problem". I don't see much use in forcing javascript into classical oo patterns. Read http://www.crockford.com/javascript/inheritance.html, especially the very last (added) line.
KooiInc
I'll read Crockford, I see the link below. In the meantime, I've extended my example, hope this is better than the previous.
Adam
+2  A: 

Maybe by storing the name inside another object?

var instances = {};
instances['theNameTheUserChose'] = new MyObject();
juandopazo
This wasn't quite the approach that I took. I used this example of code: function BlindCart(){ this.Blinds = new Array(arguments.length); for(i=0;i<arguments.length;i++){ this.Blinds[i] = arguments[i]; } }...essentially following the advice here. I thought I would need to ref by name, but the app doesn't really require that. The names I had intended to give the objects are stored in the objects now
Adam
A: 

You are always going to have to have some sort of reference to your type. Lets say you create a constructor function (class) and call it MyObject. If I understand you correctly the use case is that your users should be able to do something like this instead:

var userObject = new SomethingElse(); // instead of new MyObject();

This is programming, so you are always going to have to be explicit. You could do something like this:

var types = {};
types["aType"] = MyObject;
var userObject = new types["aType"];

Note that even though you do like above, your users are going to have to know what the "aType" property of the "types" object contains. You can't really do something like this:

var userObject = guessTheClassName();

Hope this helps.

Helgi
I hope my new example is a better description - I think the answer you've given solves a problem where the unknown is the other side of the = symbol.
Adam