View Full Version : eval, and names vs. references
krycek
11-06-2002, 08:54 PM
I have got myself stuck, stuck, stuck :(
I am trying to convert a name into a reference, but going nowhere fast. The weird thing is, I have a function I wrote which works like this:
this.name = name
this.ref = eval(name)
this.name is hence a string of the object name, and this.ref is a reference to the object.
I do not know if that is the proper method to do it, but it seems to work!
My problem is that I have built a constructor function, which creates an object and assigns stuff to it. It goes something like this:
function customObject() {
this.property1 = "hello"
this.property2 = "nice day"
}
customObject.prototype.displayIt(what) {
alert(what)
}
function createMyObject(name) {
eval(name + "=new customObject()")
ref = eval(name)
ref.property1 = "hi"
ref.displayProps = function() {
alert(ref.property1 + ", " + ref.property2)
}
The basic idea is that I have a "basic" object that I can use, and also a constructor to make an "advanced" object based on the basic object. The advanced object adds a few more properties and methods.
The trouble is that for some reason, all the new properties and methods are being assigned to "ref"!!! i.e. ref is being treated as an object rather than a reference to an object.
I tried changing the "ref" in displayProps to "this" but it still would not do the task! I only found out what it was doing by inserting loads of alerts and keeping track of property values. Because it is treating "ref" as an object, it will only look at the last incarnation of customObject!
I am really not sure how to treat this - I cannot use document.all[name] or getElementByID, because this is a script-only object, and does not exist in the HTML.
Ideas, please...? :confused:
::] krycek [::
beetle
11-06-2002, 09:18 PM
Shot in the dark. Try...
this.name = name
this.ref = window[name]
??
krycek
11-06-2002, 09:48 PM
well, I can't use this. ... because the function createMyObject exists only to create a new version of customObject, with extra properties and methods.
but, I tried ref = window[name] and still no joy. :(
...any other ideas...? :confused:
I have been trawling the web for a few hours now, with no luck...
::] krycek [::
Roy Sinclair
11-06-2002, 10:00 PM
Does this get you the result you expected?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Testing</title>
<style type="text/css">
</style>
<script language="javascript" type="text/javascript">
function customObject()
{
this.property1 = "hello"
this.property2 = "nice day"
}
function customObject.prototype.displayIt(what)
{
alert(what)
}
function createMyObject(name,prp1)
{
eval("var ref =" + name + "=new customObject()")
ref.property1 = prp1
ref.displayProps = function()
{
alert(ref.property1 + ", " + ref.property2)
}
}
</script>
</head>
<body>
<script language="javascript" type="text/javascript">
createMyObject("obj1","Yo");
createMyObject("obj2","Greetings");
obj2.displayProps();
</script>
</body>
</html>
krycek
11-06-2002, 10:23 PM
OMG!!! :eek: It WORKS! :eek:
I am forever in your debt, kind sir...! :D
I understand what you did... but I didn't know that it was possible in JavaScript!
eval("var ref =" + name + "=new customObject()")
would the same technique work for:
var value1 = value2 = "hello"?
i.e. is that valid coding practice? A brief explanation would be very helpful :)
Just one other thing...
function createMyObject(name,prp1)
{
eval("var ref =" + name + "=new customObject()")
ref.property1 = prp1
ref.displayProps = function()
{
alert(ref.property1 + ", " + ref.property2)
}
}
should the line:
alert(ref.property1 + ", " + ref.property2)
be referring to ref, or to this, or does it not matter? It seems to work both ways, but I am not entirely sure how things are being assigned there... which is the proper procedure to use?
Many, many, many thanks! :cool:
::] krycek [::
mordred
11-06-2002, 11:32 PM
In most cases, multiple assignment should work, although it looks unusual. However, here's an alternative that goes without invoking eval:
function createMyObject(name,prp1) {
this[name] = new customObject();;
this[name].property1 = prp1;
this[name].displayProps = function() {
alert(this.property1 + ", " + this.property2)
}
}
And used with the following code, you'll see that the eval solution tied the returned object to the window scope, not the one of a custom object... although I haven't investigated too much into this, it's just a quick shot, anyway here it is:
var b = new Object();
b.createMyObject = createMyObject;
b.createMyObject("obj1","Yo");
b.createMyObject("obj2","Greetings");
b.obj2.displayProps(); // throws error with eval in createMyObject, not so with 'this'
Last note: All tests done in IE5.5 on Win2k, if that should matter.
krycek
11-06-2002, 11:55 PM
Thanks mordred... it looks very interesting and I have been trying to implement it in my code :)
However I have a problem:
I notice that in your method, the outer function assigns by this[name], but the inner ones by this.
Well, how would I address the parent from an inner function? i.e. -
function createMyObject(name, prp1, prp2) {
this[name] = new customObject();;
this[name].property1 = prp1;
this[name].displayProps = function() {
alert(this.property1 + ", " + this.property2)
}
this[name].level2 = new customObject()
this[name].level2.property1 = prp2
this[name].displayProps = function() {
alert(this.property1)
...call level 1 .displayProps()
}
}
How would I do that? Would it be this.parentObject.displayProps() ? or, .parentElement? or, .....?
Your help is much appreciated and I can see where you re going with this - it is a more robust solution than the other, even though that worked :)
::] krycek [::
krycek
11-07-2002, 12:13 AM
well, I managed to do it... sort of!
I have not done it in what I would consider the "proper" way, that is, addressing the parent object through the object hierarchy - instead, I have set a property parentRef and another parentName, which are set to this[name] and name respectively.
This allows my to call a function that is up one level... but if later I need to call up two levels, I am stuck again... which is why I would still like to know how to do this :)
Cheers for your help, I have the code working perfectly now but of course would like to polish it off using the required technique :D
::] krycek [::
mordred
11-07-2002, 08:09 AM
Originally posted by krycek
I notice that in your method, the outer function assigns by this[name], but the inner ones by this.
The "inner ones" don't assign anything - they just alert the values they looked up in the object they refer to (in this case, this[name], or "b.obj2".
Well, how would I address the parent from an inner function? i.e. -
Well... I think I don't understand you completely. What do you mean by "parent"? Should it be the object you created by new CustomObject() - which is already done by using "this" - or do you refer to the object to which you assign this object by invoking createMyObject() - in this case: "b"? (Hope I don't confuse the hell out of you).
function createMyObject(name, prp1, prp2) {
this[name] = new customObject();;
this[name].property1 = prp1;
this[name].displayProps = function() {
alert(this.property1 + ", " + this.property2)
}
this[name].level2 = new customObject()
this[name].level2.property1 = prp2
this[name].displayProps = function() {
alert(this.property1)
...call level 1 .displayProps()
}
}
What is "level 1" for you in this context. Furthermore, have you noticed that you override the first displayProps method?
Here's a code snippet that shows some posibilities to alert properties of different object hierarchy. As you suggested, passing explicitly a reference to a parent object should be sufficient enough to provide a way of chaining together an object hierarchy, in the same way like you create a linked list.
function createMyObject(name, par, prp1, prp2, prp3, prp4) {
this[name] = new customObject();;
this[name].property1 = prp1;
this[name].property2 = prp2;
this[name].level2 = new customObject()
this[name].level2.property1 = prp3;
this[name].level2.property2 = prp4;
// this[name].parent = par; // set the parent explicitly
this[name].parent = this; // or set the parent object from the hierarchy
this[name].displayProps = function() {
alert(this.parent.myParentProp);
alert(this.property1 + ", " + this.level2.property1)
alert(this.property2 + ", " + this.level2.property2);
}
}
....
var b = new Object();
b.createMyObject = createMyObject;
b.myParentProp = "bla"; // this will be shown in the alert
b.createMyObject("obj1", b, "Yo", "Yo");
b.createMyObject(
"obj2",
b,
"Greeting of level 1",
"property of level 1",
"Greeting of level 2",
"property of level 2"
);
b.obj2.displayProps();
Roelf
11-07-2002, 08:16 AM
a while ago i came across this tutorial about object-inheritance implemented in JavaScript http://www.kevlindev.com/tutorials/javascript/inheritance/index.htm maybe you could use that to achieve what you want.
krycek
11-09-2002, 01:42 AM
Mordred - very sorry for not replying earlier, but I took the time to go through everything you said and test it out. I must say a big thankyou for going to the trouble of doing all that, but it was worth it to me because it certainly helped a lot! :thumbsup:
Sorry about that bit of the code that overwrote itself, it was supposed to be on level2. I have got the referencing to parents etc. sussed now, and of course silly me I can refer back as far as, by going:
this.parent.parent.parent... etc.
so that is not a problem.
The only thing that seems weird is the way you do:
var b = new Object();
b.createMyObject = createMyObject;
b.myParentProp = "bla"; // this will be shown in the alert
b.createMyObject("obj1", b, "Yo", "Yo");
But, I guess that because the creation function refers to things relative to this[name], the 'this' has to be relative to the place in the hierarchy that the new object has to go. So although I am not over-enthusiastic about sticking the creation function in there, I have been thinking about it and I reckon it is the best method. After all I can always null it after creation if I really want :)
It is such a good thing that you included that bit of code, though, because I did not realise how to do this, and was literally on the verge of taking my function apart again to somehow pass to it the object to nest it in. Your way is a lot cleaner, and means I do not have to alter my code at all! :D
Cheers for everything - feel free to bother me with any problems you may have in the future :cool:
::] krycek [::
PS - Roelf - I looked at that article, but I have to admit it was a bit over my head, although maybe that was because I did not have time to study it at leisure. I intend to return to it when I get the chance, and try out a few exercises, because it looks most intriguing! (Although step one will be to work out wtf the guy is going on about! lol!)
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.