JavaScript Object and Prototypes  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| |
JavaScript is a very strange place for me...
So, I decided that, before I attempt to create an Object, I should first learn about Objects. I had actually created one before with the help of a tutorial. The tutorial was complicated because showed me how to create a JavaScript Object that is a representation my .NET Object and how to get the two to "work together as one".... apparently the tutorial was not very clear about what was going on in the JavaScript Object...and even with my extensive commenting of the JavaScript Object I still didn't "really" know what was going on...at the time I was more interested in the .NET concepts than the JavaScript techniques being used in the tutorial.
Anyways, I started with the basics: how do I create a JavaScript Object.
To my surprise all functions were Objects, all Objects were Functions and I was not pleased with this new way of thinking because it's really strange...but it's just how things are.
The next thing I did was try to figure out what I had done to create the JavaScript Object in the tutorial. This Object uses the prototype property (which is apparently an Object and is a property of all functions) to add functions and properties to the Object.
So I started playing around with a silly little (uncomplicated) Object of my own...
Please see the comments in the following code for what I'm confused about : -
<html>
-
<body>
-
-
<script type="text/javascript">
-
-
/*Welcome to my little Foo Class experimentation.
-
The following function is a "constructor function",
-
that will create an instance of my Foo Object*/
-
function Foo(firstNumber,secondNumber){
-
this.a = firstNumber; //"a" is now a property of the Foo Object
-
this.b = secondNumber;//"b" is now a property of the Foo Object
-
this.Multiply = function(){return this.a * this.b;}//Multiply is now a method for my Foo Object
-
this.Divide = function(){return "you're in Foo's Divide function";}
-
//The Divide method is NOT overwritten by the Divide method in the prototype Object
-
-
/*
-
The following does not work.
-
Even though it does work when I use the same sort of
-
thing to "overwrite" the prototype Object.
-
-
Why??
-
*/
-
-
/*a: firstNumber,
-
b: secondNumber,
-
Multiply: function(){return this.a * this.b;}*/
-
};
-
-
//This was my first experiment:
-
//I used the prototype property to add the Divide method to the Foo Class
-
/*Foo.prototype.Divide = function(){return this.a/this.b;};*/
-
-
//This is my second experiment:
-
//overwrite the prototype Object
-
//This works fine but...
-
//What is with the colons (:) and commas (,)??
-
//I don't get it
-
Foo.prototype = {
-
Add: function(){return this.a + this.b},
-
Divide: function(){return this.a/this.b;}
-
};
-
-
var instanceOfFoo = new Foo(2,3);
-
-
//JavaScript couldn't find Add in the Foo class
-
//it looks to the prototype Object and finds it there
-
document.write(instanceOfFoo.Add());
-
document.write("<br />");
-
document.write(instanceOfFoo.Multiply());
-
document.write("<br />");
-
-
//The Divide method is found in the Foo class and is used
-
//instead of the one defined in the prototype
-
document.write(instanceOfFoo.Divide());
-
document.write("<br />");
-
-
//The following doesn't work...
-
//how do you access the Divide method in the prototype???
-
//document.write(instanceOfFoo.prototype.Divide());
-
//document.write("<br />");
-
document.write("<br />");
-
-
-
var anotherInstanceOfFoo = new Foo(10,2);
-
document.write(anotherInstanceOfFoo.Add());
-
document.write("<br />");
-
document.write(anotherInstanceOfFoo.Multiply());
-
document.write("<br />");
-
document.write(anotherInstanceOfFoo.Divide());
-
document.write("<br />");
-
document.write("<br />");
-
-
instanceOfFoo.newProperty = "instanceOfFoo's property";//adds a property named "newProperty" to the instanceOfFoo live Object.
-
document.write(instanceOfFoo.newProperty);
-
document.write("<br />");
-
document.write(anotherInstanceOfFoo.newProperty);//is undefined because it is only available to the instanceOfFoo live Object
-
document.write("<br />");
-
document.write("<br />");
-
-
//Adding a property named "newProperty" to the prototype object of the Foo class
-
//This makes it available to all instances of the Foo class (live ones too)
-
Foo.prototype.newProperty ="newly added property to prototype which is available to all
-
instances of Foo.";
-
-
//It's interesting that the original value for the "newProperty" property is kept
-
document.write(instanceOfFoo.newProperty);
-
document.write("<br />");
-
document.write(anotherInstanceOfFoo.newProperty);//now contains a value
-
document.write("<br />");
-
-
</script>
-
-
</body>
-
</html>
Thanks for your help clarifying the questions in the above posted code!
-Frinny
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
ok .... let's have a closer look at it :) ...
typically you create a constructor like this: -
function MY_OBJ() {
-
this.prop = 'foo';
-
this.func = function() { //whatever code };
-
}
-
-
// use the constructor
-
var my_obj = new MY_OBJ;
-
you cannot mix that with the : notation of properties ... the properties are declared with this.prop in the above case, and need explicit assignments.
Now you could even create a new object like this literally: -
var foo = {
-
a: 'some_value',
-
b: function() { // whatever code }
-
};
-
here you create an instance of an object directly and you declare the properties a and b ... where b stores a reference to the function-code that is assigned to it. note: when you have a look at this ... this is where JSON is not far away ;) just have that as a string from a response and eval it and you have a native js-object ready for use.
so when you do: -
some_obj.prototype = {
-
// whatever
-
};
-
you create a new prototype-obj with the properties/methods you want the some_obj to have.
the 'classical' way to do that is: -
some_obj.prototype.my_new_function = function() {
-
// function's code
-
}
-
so you just extend the prototype of the obj with just one property/method instead of overwriting the entire prototype. now you are asking how to call a method ... this is quite simple. when you have an instance you just call it like this: - obj_instance.method_name();
when you want to use the method without an instance, then just use: - constructor_name.prototype.method_name();
i hope this helps you? :)
kind regards
PS: be aware of the use of the this keyword when working with javascript object ... this always relates to the caller of a function ... so that might be tricky when starting to use objects in JavaScript.
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes Quote:
Originally Posted by gits ok .... let's have a closer look at it :) ...
you cannot mix that with the : notation of properties ... the properties are declared with this.prop in the above case, and need explicit assignments. What is the name of the ":" notation so that I can look this up? Quote:
Originally Posted by gits Now you could even create a new object like this literally: -
var foo = {
-
a: 'some_value',
-
b: function() { // whatever code }
-
};
-
where you create an instance of an object directly and...
-
Ok, "overwriting" makes sense to me now, thanks. Quote:
Originally Posted by gits now you are asking how to call a method ... this is quite simple. when you have an instance you just call it like this: - obj_instance.method_name();
when you want to use the method without an instance, then just use: - constructor_name.prototype.method_name();
This is not exactly what I was asking.
I've defined 2 versions of the Divide() method: one in the Foo class and the other is in Foo's prototype.
The Divide() method in the Foo class simply returns a String stating that "you're in Foo's Divide function".
The Divide() method in Foo's prototype divides "a" property by "b" property.
I'm wondering how to call the Divide() method in the prototype for a live instance of Foo.....not how to statically call the Divide() method in the prototype...I don't know if I'm being clear here so if you don't understand my question I can try and restate it.
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
the prototype is first parsed and later when you create the instance then the member-variables are allocated. when you have a prototype-property for the obj and then create a member directly this will drop the reference to the prototypes method for this obj. so the member will 'override' the prototype for this instance ... you only could call it staticly
using the prototype is to prefer because members will always alloc memory while the prototype is read and parsed only once.
kind regards
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
ahh ... and i don't know whether there is a name for the : - notation ... it could only be used when you create JavaScript-objects through the literals {}: - var a = {};
-
-
// is equivalent to:
-
-
var a = new Object;
kind regards
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes Quote:
Originally Posted by gits the prototype is first parsed and later when you create the instance then the member-variables are allocated. when you have a prototype-property for the obj and then create a member directly this will drop the reference to the prototypes method for this obj. so the member will 'override' the prototype for this instance ... you only could call it staticly Ok I didn't know this. In fact I had a completely different view on this. I thought that the JavaScript engine would fist search the Object for the property/method and if it couldn't find it it would then search the prototype....
I thought the reason for why I couldn't get to the prototype's method was because the JavaScript engine found the method in the Object and simply used that method.
Are you saying that if there is a method defined in the Object, that there is no possible way to access a method with the same name in the prototype because it's being overwritten?
This honestly seems a bit backwards to me....I was thinking that I could use the prototype object to "extend" functionality of existing objects....but if I can't overwrite the existing methods then this idea obviously wont work.
This is disappointing Quote:
Originally Posted by gits using the prototype is to prefer because members will always alloc memory while the prototype is read and parsed only once. This will let allow for extended functionality on existing methods/properties as well...?? (testing)
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
not exactly ... it is the following way:
1. script is loaded and parsed ... so even all prototypes are parsed for the classes first - all prototype-props become part of this for the constructor
2. now you create an instance -> the constructor is executed ... and the new function is assigned to the name that first had a reference to the prototypes method.
to overwrite you have to create a instance first and then overwrite the method for that instance or make use of inheritance and use different classes: - function FOO() {}
-
-
FOO.prototype.my_func = function() {};
-
-
function CHILD_FOO() {}
-
-
CHILD_FOO.prototype = new FOO;
-
-
CHILD_FOO.prototype.constructor = CHILD_FOO;
-
-
CHILD_FOO.prototype.my_func = function() {};
-
-
var child_foo = new CHILD_FOO;
-
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes
I'll try your example in a sec...
But this is working: - <html>
-
<body>
-
-
<script type="text/javascript">
-
-
function Foo(firstNumber,secondNumber){
-
this.a = firstNumber; //"a" is now a property of the Foo Object
-
this.b = secondNumber;//"b" is now a property of the Foo Object
-
};
-
Foo.prototype = {
-
Add: function(){return this.a + this.b;},
-
Divide: function(){return this.a/this.b;},
-
Multiply: function(){return this.a * this.b;}
-
};
-
-
function GrownUpFoo(firstNumber, secondNumber, thirdNumber){
-
this.Foo = new Foo(firstNumber, secondNumber);
-
this.c = thirdNumber;
-
};
-
-
GrownUpFoo.prototype = {
-
Multiply: function(){return this.Foo.a * this.Foo.b * this.c;}
-
};
-
-
-
var instanceOfGrownUpFoo = new GrownUpFoo(2,3,4);
-
document.write(instanceOfGrownUpFoo.Multiply());
-
document.write("<br />");
-
document.write(instanceOfGrownUpFoo.Foo.Multiply());
-
-
</script>
-
-
</body>
-
</html>
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes Quote:
Originally Posted by gits not exactly ... it is the following way:
1. script is loaded and parsed ... so even all prototypes are parsed for the classes first - all prototype-props become part of this for the constructor
2. now you create an instance -> the constructor is executed ... and the new function is assigned to the name that first had a reference to the prototypes method.
to overwrite you have to create a instance first and then overwrite the method for that instance or make use of inheritance and use different classes: Ok that's basically what I did in my experiment.
This method also allows me to overwrite the method defined in the "class" function of the base... -
<html>
-
<body>
-
-
<script type="text/javascript">
-
-
function Foo(firstNumber,secondNumber){
-
this.a = firstNumber; //"a" is now a property of the Foo Object
-
this.b = secondNumber;//"b" is now a property of the Foo Object
-
this.Multiply = function(){return this.a * this.b;};
-
};
-
Foo.prototype = {
-
Add: function(){return this.a + this.b;},
-
Divide: function(){return this.a/this.b;},
-
};
-
-
function GrownUpFoo(firstNumber, secondNumber, thirdNumber){
-
this.Foo = new Foo(firstNumber, secondNumber);
-
this.c = thirdNumber;
-
};
-
-
GrownUpFoo.prototype = {
-
//The following agumetns the multiply method
-
Multiply: function(){return this.Foo.Multiply() * this.c;}
-
};
-
-
-
var instanceOfGrownUpFoo = new GrownUpFoo(2,3,4);
-
document.write(instanceOfGrownUpFoo.Multiply());
-
document.write("<br />");
-
document.write(instanceOfGrownUpFoo.Foo.Multiply());
-
-
</script>
-
-
</body>
-
</html>
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes
Thanks a lot for your help Gits!
I have a much better understand about the JavaScript engine, JavaScript Objects, and even inheritance in JavaScript.
:)
-Frinny
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes
Just to recap everything I learned here:
There are 2 ways to define and use a class in JavaScript.
The fist allows you to define a class and use it to create multiple instances (objects) of it.
The other defines a class and creates an instance of it at the same time (literally) but cannot be used to create more instances of the class..
To create a class that you can create multiple instances of you need to define it like: - function MY_CLASS() {
-
this.aProperty = 'foo';
-
this.aFunction = function() { return "something"; };
-
}
Then you can use it to create multiple instances: -
var firstMyClassInstance = new MY_CLASS();
-
var secondMyClassInstance = new MY_CLASS();
-
var thirdMyClassInstance = new MY_CLASS();
If you don't need to more than one instance of the class, you can define one and create an instance of it at the same time by: -
//the variable anObject is an object that is an instance of the class defined inline/litterally
-
var anObject= {
-
aProperty: 'some_value',
-
aFunction: function() { return "something";}
-
};
Also the prototype property is an Object that is part of every Object.
It is used to provide additional properties/methods to an Object but is not to be used to "overwrite" any properties/methods in the class that is a part of. The JavaScript engine loads and parses the prototype Object and anything defined within the prototype becomes part the Object that the prototype belongs to.
This is why my attempts to overwrite the method defined in the "class" function with a method defined in the prototype property was failing.
You cannot use the prototype property like inheritance, to overwrite the methods in the class that is is a part of.
You have to properly create a new derived class that inherits the first class in order to extend functionality in the base class.
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
no problem ... glad i could have been of some help :)
kind regards,
gits
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes Quote:
Originally Posted by Frinavale Also the prototype property is an Object that is part of every Object.
It is used to provide additional properties/methods to an Object but is not to be used to "overwrite" any properties/methods. that's right except when you use inheritance ... as you see in my previous example ... the inheritance was made by overwriting the prototype of the child-obj with a new instance of the parent-class and then you could overwrite the inherited method with a new one ... in the child-obj's class
kind regards
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
and just one more note for optimizing it a bit: when you create an instance without any parameters for the constructor then you might leave out the brackets ... this avoids the parsing of an empty args list for the parser and performs better ;)
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes Quote:
Originally Posted by gits that's right except when you use inheritance ... as you see in my previous example ... the inheritance was made by overwriting the prototype of the child-obj with a new instance of the parent-class and then you could overwrite the inherited method with a new one ... in the child-obj's class
kind regards
Haha, don't try and confuse me now, I've finally got it!
:)
The only way to overwrite a method defined in a "class" function is to create a new "child-class" function. This child class is able to overwrite the methods in the parent-class.
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes
Ok, now that I think I understand how Objects work in JavaScript, I'm off to look up how to implement a Singleton pattern using JavaScript.
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
;) nope ... you could even do (for a specific instance): -
function MY_OBJ() {}
-
-
MY_OBJ.prototype.my_func = function() {};
-
-
var o = new MY_OBJ;
-
-
o.my_func = function() { // new code here };
kind regards
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
hmmm ... a singleton :) something like this: -
function MY_OBJ() {
-
if (this.o != null) {
-
return MY_OBJ.prototype.o;
-
} else {
-
MY_OBJ.prototype.o = this;
-
}
-
}
-
-
MY_OBJ.prototype.o = null;
-
-
MY_OBJ.prototype.my_func = function() {};
-
-
var o = new MY_OBJ;
-
-
o.foo = 'foo';
-
-
alert(o.foo);
-
-
var a = new MY_OBJ;
-
-
a.foo = 'bar';
-
-
alert(a.foo);
-
alert(o.foo);
kind regards
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes
:D
You know what's funny?
I decided that I don't actually want to use the Singleton in my solution.
;)
Thanks again Gits!
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
*lol* ... but it's quite cool ;) ... nope ... serious ... when you have a look at it it makes use of the things we talked about before ... when we first create an instance we overwrite the prototype of the class and when the second instance should be created we just return a ref to the first created object ;)
kind regards
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes Quote:
Originally Posted by gits when you have a look at it it makes use of the things we talked about before ... I was thinking the same thing.
It is pretty cool, and thanks to you it makes a lot of sense to me now.
I have a long way to go with JavaScript. As my ASP.NET applications become more complicated I'm finding that I have to use JavaScript more and more. It's a really good thing that you've helped me understand these basics now because I have a feeling everything's about to become a lot more complicated in my future.
|  | Moderator | | Join Date: May 2007 Location: Munich, Germany
Posts: 4,136
| | | re: JavaScript Object and Prototypes
you know where to find help ;) ... JavaScript is quite cool!! :)
kind regards,
gits
|  | Moderator | | Join Date: Aug 2008 Location: Leipzig, Germany
Posts: 3,660
| | | re: JavaScript Object and Prototypes Quote:
Originally Posted by Frinavale What is the name of the ":" notation so that I can look this up? "Object Literal" (just to give that info)
|  | Site Moderator | | Join Date: Oct 2006 Location: The Great White North
Posts: 5,137
| | | re: JavaScript Object and Prototypes Quote:
Originally Posted by gits ok .... let's have a closer look at it :) ... -
var foo = {
-
a: 'some_value',
-
b: function() { // whatever code }
-
};
-
here you create an instance of an object directly and you declare the properties a and b ... where b stores a reference to the function-code that is assigned to it. note: when you have a look at this ... this is where JSON is not far away ;) just have that as a string from a response and eval it and you have a native js-object ready for use. I started debugging my original Ajax enabled .net server control (again...because it's not working in IE8... in fact it's crashing IE8 RC1). Upon researching a way around my problems I encountered numerous references to JSON with regards to these types of controls. Curious, I finally looked into JSON and now understand what you were referring to in your comment here. Quote:
Originally Posted by gits PS: be aware of the use of the this keyword when working with javascript object ... this always relates to the caller of a function ... so that might be tricky when starting to use objects in JavaScript. I find it ironic that I had to experience this problem first hand myself even though you warned me about ""this"".
|  | Similar JavaScript / Ajax / DHTML bytes | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,471 network members.
|