Solved

Using "this" in object literal notation in prototype

Posted on 2007-11-14
20
362 Views
Last Modified: 2012-05-05
I'd like to do this:

//the class:

      function message(text) {
       var me = this;
       me.G.text = text;
      }
      
      //note use of globals here
      message.prototype.G = {
        text:null
      }
      
//the main problem is here
      message.prototype.parent = {
        me:this,
        new:function(){
              var me = this.me;
              var statement = me.G.text;
              return statement;
        },
        old:function(){
              var me = this;
              var something = me.G.text + "foo";
              return something;
        }
      }
      
      message.prototype.show = function(){
        var show = this.parent.new();
        alert(show);
      }
      
      //instance of class
      var msg = new message("hello");
      msg.show();


unfortunately, there doesn't seem to be a way to reference the "this" property of the class, so that i can have access to the other prototyped functions. I know I can rewrite this as separate functions, but i like grouping similar functions together like this-
0
Comment
Question by:chrismarx
  • 11
  • 9
20 Comments
 
LVL 63

Accepted Solution

by:
Zvonko earned 500 total points
Comment Utility
Does "this" help you :)


<script>

//the class:

      function message(text) {
       var me = this;
       this.G = {
        text:text
       }
       this.parentMsg =  {
        newMsg:function(){
              var statement = me.G.text;
              return statement;
        },
        oldMsg:function(){
              var me = this;
              var something = me.G.text + "foo";
              return something;
        }
       }
       this.showMsg = function(){
        var show = me.parentMsg.newMsg();
        alert(show);
       }
      }
     

     
     
      //instance of class
      var msg = new message("hello");
      msg.showMsg();


</script>



0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Sorry, better check this:


<script>
 

//the class:
 

      function message(text) {

       var me = this;

       this.G = {

        text:text

       }

       this.parentMsg =  {

        newMsg:function(){

              var statement = me.G.text;

              return statement;

        },

        oldMsg:function(){

              var something = me.G.text + "foo";

              return something;

        }

       }

       this.showMsg = function(){

        var show = me.parentMsg.newMsg();

        alert(show);

       }

      }

      
 

      

     

      //instance of class

      var msg = new message("hello");

      msg.showMsg();
 
 

</script>

Open in new window

0
 

Author Comment

by:chrismarx
Comment Utility
thats is good to know, but my problem here is really stemming from that fact that i need to use the prototype property -- the example is just a extreme simplification of my actual problem, which is with a huge class that i wrote.

 stepping away from the above example for a moment, i really would just like some way to create a prototyped method that creates/returns more than 1 function. in other words, i just need to be able to call a function that looks like this

this.parentFunction.childFunction();

somewhere within the class itself, not from outside from the instantiated object. up until this point, i've got around this issue using a real back hack

message.prototype.me = function() {return this};

which i could call from anywhere in the class (even in the object literal), but i realized later that this was going to cause problems when i tried to create multiple objects and tried to override some of the methods; the class didnt operate as expected because alternate instantiations of the object were still calling the original instance of this! (doh!)
0
 

Author Comment

by:chrismarx
Comment Utility
just to be clear, the "bad" hack, referenced the original class because i used the call like this

 message.prototype.parent = {

        new:function(){

              var me = message.prototype.me();    //note the hack

              var statement = me.G.text;

              return statement;

        },

        old:function(){

              var me = message.prototype.me();  //note the hack

              var something = me.G.text + "foo";

              return something;

        }

      }

Open in new window

0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
You described the problem in your last paragraph.
The same problem that you get "me" overwritten when you call it multiple times is that you get never parentFunction instatiated when no statement is executed. The definition alone does not create it as Object.

So my question to you is: at what point in time do you expect that parentFunction is assigned by execution of the definition statements?




0
 

Author Comment

by:chrismarx
Comment Utility
the parentFunction is never called from outside the class itself, just like in my first example. It's only called by other methods that do get called from instantiated object.
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility

How about this from me :)


<script>
 

//the class:
 

      function message(text) {

       var me = this;

       me.G.text = text;

       me.parentMsg.me = me;

      }

      

      //note use of globals here

      message.prototype.G = {

        text:null

      }

      

//the main problem is here

      message.prototype.parentMsg = {

        me: null,

        newMsg:function(){

              var statement = this.me.G.text;

              return statement;

        },

        oldMsg:function(){

              var something = this.me.G.text + "foo";

              return something;

        }

      }

      

      message.prototype.show = function(){

        var show = this.parentMsg.newMsg();

        alert(show);

      }

      

      //instance of class

      var msg = new message("hello");

      msg.show();
 

</script>

Open in new window

0
 

Author Comment

by:chrismarx
Comment Utility
way cool!!

i think this has already been worth 500 points, so if you want me to open a new question i will, because although my next question is directly related, you have answered the original question. either way, here goes

1. populating the object literals with references to this is brilliant. just to be sure though, do you see any problem (as in performance) with doing this with multiple objects? ie
 
me.parentMsg1.me = me;
me.parentMsg2.me = me;
me.parentMsg3.me = me;
etc..

2. here is more troubling question. i've now added the function that creates another instance of the message class and overrides one of the properties. however, as you will see, overriding the method in the second object now seems to also affect the first -- what am i doing wrong?

//class

    

   function message(text) {

       var me = this;

       me.G.text = text;

       me.parentMsg.me = me;

    }

      

    //note use of globals here

    message.prototype.G = {

        text:null

      }

      

      message.prototype.parentMsg = {

        me: null,

        newMsg:function(){

              var statement = this.me.G.text;

              return statement;

        },

        oldMsg:function(){

              var something = this.me.G.text + "foo";

              return something;

        }

      }

      

      message.prototype.show = function(){

        var show = this.parentMsg.newMsg();

        alert(show);

      }

      

      // first instance of message class

      var msg = new message("hello");

      

      //msg.show() -- calling this here alerts "hello"
 

 // second instance of message class
 

	function message2() {}

	message2.prototype = new message("goodbye");

	message2.prototype.constructor = message2;

	message2.prototype.parentMsg.newMsg = function(){ 

	  var statement = this.me.G.text + "more";

	 return statement;

	}	

	var msg3 = new message2();
 

	msg3.show();

        //alerts "goodbye more"
 

	msg.show();

        //should still alert "hello", but instead shows "goodbye more"

Open in new window

0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
every somename.prototype.morename = assigns only ONE copy of an object. Only objects created by calling new Constructor function create again and again new object copies in storage. You see?

Have a look in your favorite book how Object constructor functions work. Not everything what is not blocked by JavaScript parser as syntactical or semantical error is valid meaningfull code.
Worst example I have seen so far are this three lines:
        function message2() {}
        message2.prototype = new message("goodbye");
        message2.prototype.constructor = message2;

0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Here some comments to my last posting:


<script>
 

//not the class; this the Constructor function
 

      function message(text) {

       var me = this;

       me.G.text = text;

       me.parentMsg.me = me;

      }

      

      // one copy of property G

      message.prototype.G = {

        text:null

      }

      

//the main problem is here because you get only one Anonymous Object copy assigned as constructor property parentMsg

      message.prototype.parentMsg = {

        me: null,

        newMsg:function(){

              var statement = this.me.G.text;

              return statement;

        },

        oldMsg:function(){

              var something = this.me.G.text + "foo";

              return something;

        }

      }

      

      message.prototype.show = function(){ // this is also an static assignment but because it is only read is one copy not a problem

        var show = this.parentMsg.newMsg();

        alert(show);

      }

      

      //instance of class

      var msg = new message("hello");

      msg.show(); // you get: hello

      new message("now!");

      msg.show(); // you get: now!

      // this is because you have only one copy in storage of message.G

      alert(msg.G.text);
 

</script>

Open in new window

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:chrismarx
Comment Utility
ok, well, i took those lines right out my favorite javascript book, in the section on creating a second copy of an object and then overriding one of its methods. i understand that using "new" is the only way to get another copy, and i thought thats what i was doing. so you're saying that the code below doesn't make new copies?
var msg1= new message("hello1");
 

var msg2 = new message("hello2");
 

var msg3 = new message("hello3");

Open in new window

0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
You get three Objects of type "message", but all Objects of type "message" share one copy of property G and one copy of property parentMsg, therefore parentMsg.me last writer wins.

Sorry for this three lines:
        function message2() {}
        message2.prototype = new message("goodbye");
        message2.prototype.constructor = message2;

The first two lines make definitely sense, only I did not know that this is the way of copying constructors.
The third line I am still not understanding but I am googling :)

0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
0
 

Author Comment

by:chrismarx
Comment Utility
yes, i've been to that page before, and I thought what i was doing was pretty close, I guess i've got some details to pin down.

(back to previous post)
ok, cool, thanks for that clarification. so obviously i think you can guess my next question, how do you make copies that can maintain their own properties? I really thought that when you use new, that everything is copied. would the best way to overcome this then to create separate objects this those other functions and make a "new" instance of those objects in the message object?

or is there something on that site that shows how to do this with my exisiting object? thanks for your patience!
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
No, nothing new. All you have to do is to put all the properties that you need new copy created into Constructor that is executed at new creation time. That does say: use my first example.

You can have as many prototype definitions for methods() and readonly properties, but all properties that are writen need a copy creation in Constructor function is you need separate copies.

Here links to old questions investigating object creation and release:
http:Q_21405372.html
http:Q_21159822.html

0
 

Author Comment

by:chrismarx
Comment Utility
so i went back and looked at your original post, and it made me wonder -- what is the point of using the prototype object when you can put all your methods in the constructor using "this"?
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Good question! Why need you prototype?
From my point of view is prototype for extending built-in objects or extending base classes.

0
 

Author Comment

by:chrismarx
Comment Utility
Ok, very nice, i used your version with "this", and I was able to override one of the methods and have it affect only that instance of the class. thanks so much!!
<script>
 

//the class:
 

      function message(text) {

       var me = this;

       this.G = {

        text:text

       }

       this.parentMsg =  {

	me:me,

        newMsg:function(){

              var statement = me.G.text;

              return statement;

        },

        oldMsg:function(){

              var me = this;

              var something = me.G.text + "foo";

              return something;

        }

       }

       this.showMsg = function(){

        var show = me.parentMsg.newMsg();

        alert(show);

       }

      }

           

      //instance of class

      var msg = new message("hello");
 

      var msg2 = new message("goodbye");
 

      function message3() {}

      message3.prototype = new message("goodbye");

      message3.prototype.constructor = message3;

      message3.prototype.parentMsg.newMsg = function(){

          var statement = this.me.G.text + "more from overridden";

          return statement;

      }

 	

      var msg3 = new message3();

	
 

     msg.showMsg();

     msg2.showMsg();

     msg3.showMsg();
 
 

</script>

Open in new window

0
 

Author Closing Comment

by:chrismarx
Comment Utility
awesome!
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Thenks for this question. I learned a lot here :-)
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Batch, VBS, and scripts in general are incredibly useful for repetitive tasks.  Some tasks can take a while to complete and it can be annoying to check back only to discover that your script finished 5 minutes ago.  Some scripts may complete nearly …
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Learn the basics of if, else, and elif statements in Python 2.7. Use "if" statements to test a specified condition.: The structure of an if statement is as follows: (CODE) Use "else" statements to allow the execution of an alternative, if the …
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now