473,320 Members | 1,930 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

JavaScript Object and Prototypes

Frinavale
9,735 Expert Mod 8TB
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:

Expand|Select|Wrap|Line Numbers
  1. <html>
  2. <body>
  3.  
  4. <script type="text/javascript">
  5.  
  6. /*Welcome to my little Foo Class experimentation.
  7. The following function is a "constructor function", 
  8. that will create an instance of my Foo Object*/
  9. function Foo(firstNumber,secondNumber){
  10.   this.a = firstNumber; //"a" is now a property of the Foo Object
  11.   this.b = secondNumber;//"b" is now a property of the Foo Object
  12.   this.Multiply = function(){return this.a * this.b;}//Multiply is now a method for my Foo Object
  13.   this.Divide = function(){return "you're in Foo's Divide function";}
  14.   //The Divide method is NOT overwritten by the Divide method in the prototype Object
  15.  
  16. /*
  17. The following does not work.
  18. Even though it does work when I use the same sort of 
  19. thing to "overwrite" the prototype Object.
  20.  
  21. Why??
  22. */
  23.  
  24.   /*a: firstNumber,
  25.   b: secondNumber,
  26.   Multiply: function(){return this.a * this.b;}*/
  27. };
  28.  
  29. //This was my first experiment:
  30. //I used the prototype property to add the Divide method to the Foo Class
  31. /*Foo.prototype.Divide = function(){return this.a/this.b;};*/
  32.  
  33. //This is my second experiment:
  34. //overwrite the prototype Object
  35. //This works fine but...
  36. //What is with the colons (:) and commas (,)??
  37. //I don't get it
  38. Foo.prototype = {
  39.     Add: function(){return this.a + this.b},
  40.     Divide: function(){return this.a/this.b;}
  41. };
  42.  
  43. var instanceOfFoo = new Foo(2,3);
  44.  
  45. //JavaScript couldn't find Add in the Foo class
  46. //it looks to the prototype Object and finds it there
  47. document.write(instanceOfFoo.Add());
  48. document.write("<br />");
  49. document.write(instanceOfFoo.Multiply());
  50. document.write("<br />");
  51.  
  52. //The Divide method is found in the Foo class and is used 
  53. //instead of the one defined in the prototype
  54. document.write(instanceOfFoo.Divide());
  55. document.write("<br />");
  56.  
  57. //The following doesn't work...
  58. //how do you access the Divide method in the prototype???
  59. //document.write(instanceOfFoo.prototype.Divide());
  60. //document.write("<br />");
  61. document.write("<br />");
  62.  
  63.  
  64. var anotherInstanceOfFoo = new Foo(10,2);
  65. document.write(anotherInstanceOfFoo.Add());
  66. document.write("<br />");
  67. document.write(anotherInstanceOfFoo.Multiply());
  68. document.write("<br />");
  69. document.write(anotherInstanceOfFoo.Divide());
  70. document.write("<br />");
  71. document.write("<br />");
  72.  
  73. instanceOfFoo.newProperty = "instanceOfFoo's property";//adds a property named "newProperty" to the instanceOfFoo live Object.
  74. document.write(instanceOfFoo.newProperty);
  75. document.write("<br />");
  76. document.write(anotherInstanceOfFoo.newProperty);//is undefined because it is only available to the instanceOfFoo live Object
  77. document.write("<br />");
  78. document.write("<br />");
  79.  
  80. //Adding a property named "newProperty" to the prototype object of the Foo class
  81. //This makes it available to all instances of the Foo class (live ones too) 
  82. Foo.prototype.newProperty ="newly added property to prototype which is available to all 
  83. instances of Foo.";
  84.  
  85. //It's interesting that the original value for the "newProperty" property is kept
  86. document.write(instanceOfFoo.newProperty);
  87. document.write("<br />");
  88. document.write(anotherInstanceOfFoo.newProperty);//now contains a value
  89. document.write("<br />");
  90.  
  91. </script>
  92.  
  93. </body>
  94. </html>

Thanks for your help clarifying the questions in the above posted code!

-Frinny
Feb 20 '09 #1
23 2570
gits
5,390 Expert Mod 4TB
ok .... let's have a closer look at it :) ...

typically you create a constructor like this:

Expand|Select|Wrap|Line Numbers
  1. function MY_OBJ() {
  2.     this.prop = 'foo';
  3.     this.func = function() { //whatever code };
  4. }
  5.  
  6. // use the constructor
  7. var my_obj = new MY_OBJ;
  8.  
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:

Expand|Select|Wrap|Line Numbers
  1. var foo = {
  2.     a: 'some_value',
  3.     b: function() { // whatever code }
  4. };
  5.  
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:

Expand|Select|Wrap|Line Numbers
  1. some_obj.prototype = {
  2.     // whatever 
  3. };
  4.  
you create a new prototype-obj with the properties/methods you want the some_obj to have.

the 'classical' way to do that is:

Expand|Select|Wrap|Line Numbers
  1. some_obj.prototype.my_new_function = function() {
  2.     // function's code
  3. }
  4.  
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:

Expand|Select|Wrap|Line Numbers
  1. obj_instance.method_name();
when you want to use the method without an instance, then just use:

Expand|Select|Wrap|Line Numbers
  1. 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.
Feb 20 '09 #2
Frinavale
9,735 Expert Mod 8TB
@gits
What is the name of the ":" notation so that I can look this up?

@gits
Ok, "overwriting" makes sense to me now, thanks.

@gits
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.
Feb 20 '09 #3
gits
5,390 Expert Mod 4TB
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
Feb 20 '09 #4
gits
5,390 Expert Mod 4TB
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 {}:

Expand|Select|Wrap|Line Numbers
  1. var a = {};
  2.  
  3. // is equivalent to:
  4.  
  5. var a = new Object;
kind regards
Feb 20 '09 #5
Frinavale
9,735 Expert Mod 8TB
@gits
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
@gits
This will let allow for extended functionality on existing methods/properties as well...?? (testing)
Feb 20 '09 #6
gits
5,390 Expert Mod 4TB
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:

Expand|Select|Wrap|Line Numbers
  1. function FOO() {}
  2.  
  3. FOO.prototype.my_func = function() {};
  4.  
  5. function CHILD_FOO() {}
  6.  
  7. CHILD_FOO.prototype = new FOO;
  8.  
  9. CHILD_FOO.prototype.constructor = CHILD_FOO;
  10.  
  11. CHILD_FOO.prototype.my_func = function() {};
  12.  
  13. var child_foo = new CHILD_FOO;
  14.  
Feb 20 '09 #7
Frinavale
9,735 Expert Mod 8TB
I'll try your example in a sec...

But this is working:
Expand|Select|Wrap|Line Numbers
  1. <html>
  2. <body>
  3.  
  4. <script type="text/javascript">
  5.  
  6. function Foo(firstNumber,secondNumber){
  7.   this.a = firstNumber; //"a" is now a property of the Foo Object
  8.   this.b = secondNumber;//"b" is now a property of the Foo Object
  9. };
  10. Foo.prototype = {
  11.     Add: function(){return this.a + this.b;},
  12.     Divide: function(){return this.a/this.b;},
  13.     Multiply: function(){return this.a * this.b;}
  14. };
  15.  
  16. function GrownUpFoo(firstNumber, secondNumber, thirdNumber){
  17.    this.Foo = new Foo(firstNumber, secondNumber);
  18.    this.c = thirdNumber;
  19. };
  20.  
  21. GrownUpFoo.prototype = {
  22.      Multiply: function(){return this.Foo.a * this.Foo.b * this.c;}
  23. };
  24.  
  25.  
  26. var instanceOfGrownUpFoo = new GrownUpFoo(2,3,4);
  27. document.write(instanceOfGrownUpFoo.Multiply());
  28. document.write("<br />");
  29. document.write(instanceOfGrownUpFoo.Foo.Multiply());
  30.  
  31. </script>
  32.  
  33. </body>
  34. </html>
Feb 20 '09 #8
Frinavale
9,735 Expert Mod 8TB
@gits
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...
Expand|Select|Wrap|Line Numbers
  1. <html>
  2. <body>
  3.  
  4. <script type="text/javascript">
  5.  
  6. function Foo(firstNumber,secondNumber){
  7.   this.a = firstNumber; //"a" is now a property of the Foo Object
  8.   this.b = secondNumber;//"b" is now a property of the Foo Object
  9.   this.Multiply = function(){return this.a * this.b;};
  10. };
  11. Foo.prototype = {
  12.     Add: function(){return this.a + this.b;},
  13.     Divide: function(){return this.a/this.b;},
  14. };
  15.  
  16. function GrownUpFoo(firstNumber, secondNumber, thirdNumber){
  17.    this.Foo = new Foo(firstNumber, secondNumber);
  18.    this.c = thirdNumber;
  19. };
  20.  
  21. GrownUpFoo.prototype = {
  22. //The following agumetns the multiply method
  23.      Multiply: function(){return this.Foo.Multiply() * this.c;}
  24. };
  25.  
  26.  
  27. var instanceOfGrownUpFoo = new GrownUpFoo(2,3,4);
  28. document.write(instanceOfGrownUpFoo.Multiply());
  29. document.write("<br />");
  30. document.write(instanceOfGrownUpFoo.Foo.Multiply());
  31.  
  32. </script>
  33.  
  34. </body>
  35. </html>
Feb 20 '09 #9
Frinavale
9,735 Expert Mod 8TB
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
Feb 20 '09 #10
Frinavale
9,735 Expert Mod 8TB
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:
Expand|Select|Wrap|Line Numbers
  1.  function MY_CLASS() {
  2.     this.aProperty = 'foo';
  3.     this.aFunction = function() { return "something"; };
  4. }
Then you can use it to create multiple instances:
Expand|Select|Wrap|Line Numbers
  1. var firstMyClassInstance = new MY_CLASS();
  2. var secondMyClassInstance = new MY_CLASS();
  3. 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:
Expand|Select|Wrap|Line Numbers
  1. //the variable anObject is an object that is an instance of the class defined inline/litterally
  2. var anObject= {
  3.     aProperty: 'some_value',
  4.     aFunction: function() { return "something";}
  5. };
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.
Feb 20 '09 #11
gits
5,390 Expert Mod 4TB
no problem ... glad i could have been of some help :)

kind regards,
gits
Feb 20 '09 #12
gits
5,390 Expert Mod 4TB
@Frinavale
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
Feb 20 '09 #13
gits
5,390 Expert Mod 4TB
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 ;)
Feb 20 '09 #14
Frinavale
9,735 Expert Mod 8TB
@gits

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.
Feb 20 '09 #15
Frinavale
9,735 Expert Mod 8TB
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.
Feb 20 '09 #16
gits
5,390 Expert Mod 4TB
;) nope ... you could even do (for a specific instance):

Expand|Select|Wrap|Line Numbers
  1. function MY_OBJ() {}
  2.  
  3. MY_OBJ.prototype.my_func = function() {};
  4.  
  5. var o = new MY_OBJ;
  6.  
  7. o.my_func = function() { // new code here };
kind regards
Feb 20 '09 #17
gits
5,390 Expert Mod 4TB
hmmm ... a singleton :) something like this:

Expand|Select|Wrap|Line Numbers
  1. function MY_OBJ() {
  2.     if (this.o != null) {
  3.         return MY_OBJ.prototype.o;
  4.     } else {
  5.         MY_OBJ.prototype.o = this;
  6.     }
  7. }
  8.  
  9. MY_OBJ.prototype.o = null;
  10.  
  11. MY_OBJ.prototype.my_func = function() {};
  12.  
  13. var o = new MY_OBJ;
  14.  
  15. o.foo = 'foo';
  16.  
  17. alert(o.foo);
  18.  
  19. var a = new MY_OBJ;
  20.  
  21. a.foo = 'bar';
  22.  
  23. alert(a.foo);
  24. alert(o.foo);
kind regards
Feb 20 '09 #18
Frinavale
9,735 Expert Mod 8TB
:D

You know what's funny?
I decided that I don't actually want to use the Singleton in my solution.

;)

Thanks again Gits!
Feb 20 '09 #19
gits
5,390 Expert Mod 4TB
*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
Feb 20 '09 #20
Frinavale
9,735 Expert Mod 8TB
@gits
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.
Feb 20 '09 #21
gits
5,390 Expert Mod 4TB
you know where to find help ;) ... JavaScript is quite cool!! :)

kind regards,
gits
Feb 20 '09 #22
Dormilich
8,658 Expert Mod 8TB
@Frinavale
"Object Literal" (just to give that info)
Feb 21 '09 #23
Frinavale
9,735 Expert Mod 8TB
@gits
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.

@gits
I find it ironic that I had to experience this problem first hand myself even though you warned me about ""this"".
Mar 16 '09 #24

Sign in to post your reply or Sign up for a free account.

Similar topics

6
by: Alex Fitzpatrick | last post by:
Just by way of introduction, I'm currently the principal developer and maintainer of the a JavaScript editor plug-in for Eclipse. https://sourceforge.net/projects/jseditor/ The plug-in as it...
5
by: Greg Swindle | last post by:
Hello, I have a question about how prototyping relates to variables and their scope. Given the following code: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var ParentObject = function() {...
136
by: Matt Kruse | last post by:
http://www.JavascriptToolbox.com/bestpractices/ I started writing this up as a guide for some people who were looking for general tips on how to do things the 'right way' with Javascript. Their...
12
by: shlomi.schwartz | last post by:
Q: is it possible to inherit from a native object? I tried to use Date object as the base object like so: x.prototype = Date.prototype; x.prototype.constructor = x; function x(){...
41
by: Rene Nyffenegger | last post by:
Hello everyone. I am not fluent in JavaScript, so I might overlook the obvious. But in all other programming languages that I know and that have associative arrays, or hashes, the elements in...
7
by: Wm.M.Thompson | last post by:
For a computer programmer JavaScript is not difficult. It is pretty easy to look at some code for the first time and figure out what is going on. This is especially true if you have gratuated...
2
by: Peter Michaux | last post by:
Douglas Crockford doesn't seem to like JavaScript's built-in syntax for building new objects based on a prototype object. The constructor function, its prototype property and the "new" keyword all...
12
by: lorlarz | last post by:
Unobtrusive JavaScript leads to BUILDERS (e.g. drag drop activity builder) Once you totally remove JS from a web page, and learn the shortcuts and efficiencies provided by a library like...
4
by: Joe Hrbek | last post by:
Could someone help me translate to something that would close to it in python? The anonymous functions are giving me problems. var dataListener = { data : "", onStartRequest: function(request,...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.