Solved

Using "this" in object literal notation in prototype

Posted on 2007-11-14
20
366 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
ID: 20287333
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
ID: 20287337
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
ID: 20287388
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
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 

Author Comment

by:chrismarx
ID: 20287397
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
ID: 20287417
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
ID: 20287431
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
ID: 20287659

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
ID: 20287827
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
ID: 20294589
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
ID: 20294677
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
 

Author Comment

by:chrismarx
ID: 20294737
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
ID: 20294790
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
ID: 20294835
0
 

Author Comment

by:chrismarx
ID: 20294893
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
ID: 20295090
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
ID: 20296045
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
ID: 20299056
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
ID: 20302814
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
ID: 31409258
awesome!
0
 
LVL 63

Expert Comment

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

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Having worked on larger scale sites, we found out that you are bound to look at more scalable solutions to integrating widgets, code snippets or complete applications and mesh them into functional sites, in any given composition. To share some of…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

776 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