“this” keyword in event methods when using JavaScript prototype object












12















I'm trying to access the member variables of a prototype class in JavaScript in an event handler -- something I'd typically use the "this" keyword for (or "that" [copy of this] in the case of event handlers). Needless to say, I'm running into some trouble.



Take, for example, this HTML snippet:



<a id="myLink" href="#">My Link</a>


And this JavaScript code:



function MyClass()
{
this.field = "value"
this.link = document.getElementById("myLink");
this.link.onclick = this.EventMethod;
}

MyClass.prototype.NormalMethod = function()
{
alert(this.field);
}

MyClass.prototype.EventMethod = function(e)
{
alert(this.field);
}


Instantiating a MyClass object and calling NormalMethod works exactly like I expect it to (alert saying "value"), but clicking the link results in an undefined value because the "this" keyword now references the event target (the anchor () HTML element).



I'm new to the prototype JavaScript style, but in the past, with closures, I've simply made a copy of "this" in the constructor:



var that = this;


And then I could access members variables in event methods via the "that" object. That doesn't seem to work with prototype code. Is there another way to achieve this?



Thanks.










share|improve this question

























  • Are you referring to the Prototype library or rather straight JavaScript prototypical classes?

    – Crescent Fresh
    Sep 2 '09 at 17:24






  • 3





    Responding three years late :) But for posterity: I was referring to straight JavaScript prototypical classes.

    – Michael
    May 30 '12 at 17:25











  • Possible duplicate of How to access the correct this / context inside a callback??

    – Bergi
    Sep 9 '14 at 20:43











  • @Bergi: For the record, I asked this question in 2009. The question you linked was asked in 2013.

    – Michael
    Sep 10 '14 at 12:40











  • @Michael: Yeah, but that doesn't matter. Dupes are closed by quality of answers, not by date; the one I linked is the canonical question on loosing this. I wasn't sure whether it's an "exact" duplicate, that's why I haven't just closed it but only commented. The link is definitely helpful to everyone who visits this question.

    – Bergi
    Sep 10 '14 at 12:57
















12















I'm trying to access the member variables of a prototype class in JavaScript in an event handler -- something I'd typically use the "this" keyword for (or "that" [copy of this] in the case of event handlers). Needless to say, I'm running into some trouble.



Take, for example, this HTML snippet:



<a id="myLink" href="#">My Link</a>


And this JavaScript code:



function MyClass()
{
this.field = "value"
this.link = document.getElementById("myLink");
this.link.onclick = this.EventMethod;
}

MyClass.prototype.NormalMethod = function()
{
alert(this.field);
}

MyClass.prototype.EventMethod = function(e)
{
alert(this.field);
}


Instantiating a MyClass object and calling NormalMethod works exactly like I expect it to (alert saying "value"), but clicking the link results in an undefined value because the "this" keyword now references the event target (the anchor () HTML element).



I'm new to the prototype JavaScript style, but in the past, with closures, I've simply made a copy of "this" in the constructor:



var that = this;


And then I could access members variables in event methods via the "that" object. That doesn't seem to work with prototype code. Is there another way to achieve this?



Thanks.










share|improve this question

























  • Are you referring to the Prototype library or rather straight JavaScript prototypical classes?

    – Crescent Fresh
    Sep 2 '09 at 17:24






  • 3





    Responding three years late :) But for posterity: I was referring to straight JavaScript prototypical classes.

    – Michael
    May 30 '12 at 17:25











  • Possible duplicate of How to access the correct this / context inside a callback??

    – Bergi
    Sep 9 '14 at 20:43











  • @Bergi: For the record, I asked this question in 2009. The question you linked was asked in 2013.

    – Michael
    Sep 10 '14 at 12:40











  • @Michael: Yeah, but that doesn't matter. Dupes are closed by quality of answers, not by date; the one I linked is the canonical question on loosing this. I wasn't sure whether it's an "exact" duplicate, that's why I haven't just closed it but only commented. The link is definitely helpful to everyone who visits this question.

    – Bergi
    Sep 10 '14 at 12:57














12












12








12


4






I'm trying to access the member variables of a prototype class in JavaScript in an event handler -- something I'd typically use the "this" keyword for (or "that" [copy of this] in the case of event handlers). Needless to say, I'm running into some trouble.



Take, for example, this HTML snippet:



<a id="myLink" href="#">My Link</a>


And this JavaScript code:



function MyClass()
{
this.field = "value"
this.link = document.getElementById("myLink");
this.link.onclick = this.EventMethod;
}

MyClass.prototype.NormalMethod = function()
{
alert(this.field);
}

MyClass.prototype.EventMethod = function(e)
{
alert(this.field);
}


Instantiating a MyClass object and calling NormalMethod works exactly like I expect it to (alert saying "value"), but clicking the link results in an undefined value because the "this" keyword now references the event target (the anchor () HTML element).



I'm new to the prototype JavaScript style, but in the past, with closures, I've simply made a copy of "this" in the constructor:



var that = this;


And then I could access members variables in event methods via the "that" object. That doesn't seem to work with prototype code. Is there another way to achieve this?



Thanks.










share|improve this question
















I'm trying to access the member variables of a prototype class in JavaScript in an event handler -- something I'd typically use the "this" keyword for (or "that" [copy of this] in the case of event handlers). Needless to say, I'm running into some trouble.



Take, for example, this HTML snippet:



<a id="myLink" href="#">My Link</a>


And this JavaScript code:



function MyClass()
{
this.field = "value"
this.link = document.getElementById("myLink");
this.link.onclick = this.EventMethod;
}

MyClass.prototype.NormalMethod = function()
{
alert(this.field);
}

MyClass.prototype.EventMethod = function(e)
{
alert(this.field);
}


Instantiating a MyClass object and calling NormalMethod works exactly like I expect it to (alert saying "value"), but clicking the link results in an undefined value because the "this" keyword now references the event target (the anchor () HTML element).



I'm new to the prototype JavaScript style, but in the past, with closures, I've simply made a copy of "this" in the constructor:



var that = this;


And then I could access members variables in event methods via the "that" object. That doesn't seem to work with prototype code. Is there another way to achieve this?



Thanks.







javascript events this






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 3 '16 at 20:54









Anthony Rutledge

2,6911531




2,6911531










asked Sep 2 '09 at 17:10









MichaelMichael

99331737




99331737













  • Are you referring to the Prototype library or rather straight JavaScript prototypical classes?

    – Crescent Fresh
    Sep 2 '09 at 17:24






  • 3





    Responding three years late :) But for posterity: I was referring to straight JavaScript prototypical classes.

    – Michael
    May 30 '12 at 17:25











  • Possible duplicate of How to access the correct this / context inside a callback??

    – Bergi
    Sep 9 '14 at 20:43











  • @Bergi: For the record, I asked this question in 2009. The question you linked was asked in 2013.

    – Michael
    Sep 10 '14 at 12:40











  • @Michael: Yeah, but that doesn't matter. Dupes are closed by quality of answers, not by date; the one I linked is the canonical question on loosing this. I wasn't sure whether it's an "exact" duplicate, that's why I haven't just closed it but only commented. The link is definitely helpful to everyone who visits this question.

    – Bergi
    Sep 10 '14 at 12:57



















  • Are you referring to the Prototype library or rather straight JavaScript prototypical classes?

    – Crescent Fresh
    Sep 2 '09 at 17:24






  • 3





    Responding three years late :) But for posterity: I was referring to straight JavaScript prototypical classes.

    – Michael
    May 30 '12 at 17:25











  • Possible duplicate of How to access the correct this / context inside a callback??

    – Bergi
    Sep 9 '14 at 20:43











  • @Bergi: For the record, I asked this question in 2009. The question you linked was asked in 2013.

    – Michael
    Sep 10 '14 at 12:40











  • @Michael: Yeah, but that doesn't matter. Dupes are closed by quality of answers, not by date; the one I linked is the canonical question on loosing this. I wasn't sure whether it's an "exact" duplicate, that's why I haven't just closed it but only commented. The link is definitely helpful to everyone who visits this question.

    – Bergi
    Sep 10 '14 at 12:57

















Are you referring to the Prototype library or rather straight JavaScript prototypical classes?

– Crescent Fresh
Sep 2 '09 at 17:24





Are you referring to the Prototype library or rather straight JavaScript prototypical classes?

– Crescent Fresh
Sep 2 '09 at 17:24




3




3





Responding three years late :) But for posterity: I was referring to straight JavaScript prototypical classes.

– Michael
May 30 '12 at 17:25





Responding three years late :) But for posterity: I was referring to straight JavaScript prototypical classes.

– Michael
May 30 '12 at 17:25













Possible duplicate of How to access the correct this / context inside a callback??

– Bergi
Sep 9 '14 at 20:43





Possible duplicate of How to access the correct this / context inside a callback??

– Bergi
Sep 9 '14 at 20:43













@Bergi: For the record, I asked this question in 2009. The question you linked was asked in 2013.

– Michael
Sep 10 '14 at 12:40





@Bergi: For the record, I asked this question in 2009. The question you linked was asked in 2013.

– Michael
Sep 10 '14 at 12:40













@Michael: Yeah, but that doesn't matter. Dupes are closed by quality of answers, not by date; the one I linked is the canonical question on loosing this. I wasn't sure whether it's an "exact" duplicate, that's why I haven't just closed it but only commented. The link is definitely helpful to everyone who visits this question.

– Bergi
Sep 10 '14 at 12:57





@Michael: Yeah, but that doesn't matter. Dupes are closed by quality of answers, not by date; the one I linked is the canonical question on loosing this. I wasn't sure whether it's an "exact" duplicate, that's why I haven't just closed it but only commented. The link is definitely helpful to everyone who visits this question.

– Bergi
Sep 10 '14 at 12:57












4 Answers
4






active

oldest

votes


















9














Your "that=this" closure idiom is still applicable:



function MyClass()
{
...

var that = this;
this.link.onclick = function() {
return that.EventMethod.apply(that, arguments);

// that.EventMethod() works too here, however
// the above ensures that the function closure
// operates exactly as EventMethod itself does.

};
}





share|improve this answer

































    13














    You need:



    this.link.onclick = this.EventMethod.bind(this);


    ...'bind' is part of Prototype, and returns a function which calls your method with 'this' set correctly.






    share|improve this answer
























    • How does onclick get access to the event interface?

      – Karl
      Oct 5 '14 at 20:40













    • @Karl By "access to the event interface" do you mean "receive the event object as an argument"? The bind method returns a function (with a fixed this), so onclick = this.EventMethod is basically the same as onclick = this.EventMethod.bind(this). In both cases, you store a function in the onclick property; they're identical in terms of how their arguments are handled. If your question is more generally about how arguments are passed to listener functions, that's quite a different question than what's being asked here, and you should ask a new question.

      – apsillers
      Oct 14 '14 at 15:05





















    5














    You should try



    this.link.onclick = this.EventMethod.bind(this);





    share|improve this answer































      0














      As stated above, using bind which is a part of the Prototype library is a clean way to solve this problem. This question is a duplicate of another SO question which is answered here with implementation of the bind method without including the whole prototype library :



      https://stackoverflow.com/a/2025839/1180286






      share|improve this answer


























      • That question uses JQuery. I'd much rather see a pure JavaScript question / answer be the standard.

        – Anthony Rutledge
        Oct 3 '16 at 20:04













      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1369004%2fthis-keyword-in-event-methods-when-using-javascript-prototype-object%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      9














      Your "that=this" closure idiom is still applicable:



      function MyClass()
      {
      ...

      var that = this;
      this.link.onclick = function() {
      return that.EventMethod.apply(that, arguments);

      // that.EventMethod() works too here, however
      // the above ensures that the function closure
      // operates exactly as EventMethod itself does.

      };
      }





      share|improve this answer






























        9














        Your "that=this" closure idiom is still applicable:



        function MyClass()
        {
        ...

        var that = this;
        this.link.onclick = function() {
        return that.EventMethod.apply(that, arguments);

        // that.EventMethod() works too here, however
        // the above ensures that the function closure
        // operates exactly as EventMethod itself does.

        };
        }





        share|improve this answer




























          9












          9








          9







          Your "that=this" closure idiom is still applicable:



          function MyClass()
          {
          ...

          var that = this;
          this.link.onclick = function() {
          return that.EventMethod.apply(that, arguments);

          // that.EventMethod() works too here, however
          // the above ensures that the function closure
          // operates exactly as EventMethod itself does.

          };
          }





          share|improve this answer















          Your "that=this" closure idiom is still applicable:



          function MyClass()
          {
          ...

          var that = this;
          this.link.onclick = function() {
          return that.EventMethod.apply(that, arguments);

          // that.EventMethod() works too here, however
          // the above ensures that the function closure
          // operates exactly as EventMethod itself does.

          };
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 1 '09 at 17:54

























          answered Sep 2 '09 at 17:18









          Crescent FreshCrescent Fresh

          93.8k21141135




          93.8k21141135

























              13














              You need:



              this.link.onclick = this.EventMethod.bind(this);


              ...'bind' is part of Prototype, and returns a function which calls your method with 'this' set correctly.






              share|improve this answer
























              • How does onclick get access to the event interface?

                – Karl
                Oct 5 '14 at 20:40













              • @Karl By "access to the event interface" do you mean "receive the event object as an argument"? The bind method returns a function (with a fixed this), so onclick = this.EventMethod is basically the same as onclick = this.EventMethod.bind(this). In both cases, you store a function in the onclick property; they're identical in terms of how their arguments are handled. If your question is more generally about how arguments are passed to listener functions, that's quite a different question than what's being asked here, and you should ask a new question.

                – apsillers
                Oct 14 '14 at 15:05


















              13














              You need:



              this.link.onclick = this.EventMethod.bind(this);


              ...'bind' is part of Prototype, and returns a function which calls your method with 'this' set correctly.






              share|improve this answer
























              • How does onclick get access to the event interface?

                – Karl
                Oct 5 '14 at 20:40













              • @Karl By "access to the event interface" do you mean "receive the event object as an argument"? The bind method returns a function (with a fixed this), so onclick = this.EventMethod is basically the same as onclick = this.EventMethod.bind(this). In both cases, you store a function in the onclick property; they're identical in terms of how their arguments are handled. If your question is more generally about how arguments are passed to listener functions, that's quite a different question than what's being asked here, and you should ask a new question.

                – apsillers
                Oct 14 '14 at 15:05
















              13












              13








              13







              You need:



              this.link.onclick = this.EventMethod.bind(this);


              ...'bind' is part of Prototype, and returns a function which calls your method with 'this' set correctly.






              share|improve this answer













              You need:



              this.link.onclick = this.EventMethod.bind(this);


              ...'bind' is part of Prototype, and returns a function which calls your method with 'this' set correctly.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Sep 2 '09 at 17:20









              ijwijw

              2,69921925




              2,69921925













              • How does onclick get access to the event interface?

                – Karl
                Oct 5 '14 at 20:40













              • @Karl By "access to the event interface" do you mean "receive the event object as an argument"? The bind method returns a function (with a fixed this), so onclick = this.EventMethod is basically the same as onclick = this.EventMethod.bind(this). In both cases, you store a function in the onclick property; they're identical in terms of how their arguments are handled. If your question is more generally about how arguments are passed to listener functions, that's quite a different question than what's being asked here, and you should ask a new question.

                – apsillers
                Oct 14 '14 at 15:05





















              • How does onclick get access to the event interface?

                – Karl
                Oct 5 '14 at 20:40













              • @Karl By "access to the event interface" do you mean "receive the event object as an argument"? The bind method returns a function (with a fixed this), so onclick = this.EventMethod is basically the same as onclick = this.EventMethod.bind(this). In both cases, you store a function in the onclick property; they're identical in terms of how their arguments are handled. If your question is more generally about how arguments are passed to listener functions, that's quite a different question than what's being asked here, and you should ask a new question.

                – apsillers
                Oct 14 '14 at 15:05



















              How does onclick get access to the event interface?

              – Karl
              Oct 5 '14 at 20:40







              How does onclick get access to the event interface?

              – Karl
              Oct 5 '14 at 20:40















              @Karl By "access to the event interface" do you mean "receive the event object as an argument"? The bind method returns a function (with a fixed this), so onclick = this.EventMethod is basically the same as onclick = this.EventMethod.bind(this). In both cases, you store a function in the onclick property; they're identical in terms of how their arguments are handled. If your question is more generally about how arguments are passed to listener functions, that's quite a different question than what's being asked here, and you should ask a new question.

              – apsillers
              Oct 14 '14 at 15:05







              @Karl By "access to the event interface" do you mean "receive the event object as an argument"? The bind method returns a function (with a fixed this), so onclick = this.EventMethod is basically the same as onclick = this.EventMethod.bind(this). In both cases, you store a function in the onclick property; they're identical in terms of how their arguments are handled. If your question is more generally about how arguments are passed to listener functions, that's quite a different question than what's being asked here, and you should ask a new question.

              – apsillers
              Oct 14 '14 at 15:05













              5














              You should try



              this.link.onclick = this.EventMethod.bind(this);





              share|improve this answer




























                5














                You should try



                this.link.onclick = this.EventMethod.bind(this);





                share|improve this answer


























                  5












                  5








                  5







                  You should try



                  this.link.onclick = this.EventMethod.bind(this);





                  share|improve this answer













                  You should try



                  this.link.onclick = this.EventMethod.bind(this);






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Sep 2 '09 at 17:19









                  alex.zherdevalex.zherdev

                  20.6k75154




                  20.6k75154























                      0














                      As stated above, using bind which is a part of the Prototype library is a clean way to solve this problem. This question is a duplicate of another SO question which is answered here with implementation of the bind method without including the whole prototype library :



                      https://stackoverflow.com/a/2025839/1180286






                      share|improve this answer


























                      • That question uses JQuery. I'd much rather see a pure JavaScript question / answer be the standard.

                        – Anthony Rutledge
                        Oct 3 '16 at 20:04


















                      0














                      As stated above, using bind which is a part of the Prototype library is a clean way to solve this problem. This question is a duplicate of another SO question which is answered here with implementation of the bind method without including the whole prototype library :



                      https://stackoverflow.com/a/2025839/1180286






                      share|improve this answer


























                      • That question uses JQuery. I'd much rather see a pure JavaScript question / answer be the standard.

                        – Anthony Rutledge
                        Oct 3 '16 at 20:04
















                      0












                      0








                      0







                      As stated above, using bind which is a part of the Prototype library is a clean way to solve this problem. This question is a duplicate of another SO question which is answered here with implementation of the bind method without including the whole prototype library :



                      https://stackoverflow.com/a/2025839/1180286






                      share|improve this answer















                      As stated above, using bind which is a part of the Prototype library is a clean way to solve this problem. This question is a duplicate of another SO question which is answered here with implementation of the bind method without including the whole prototype library :



                      https://stackoverflow.com/a/2025839/1180286







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited May 23 '17 at 12:25









                      Community

                      11




                      11










                      answered Oct 25 '13 at 13:33









                      st0nest0ne

                      2815




                      2815













                      • That question uses JQuery. I'd much rather see a pure JavaScript question / answer be the standard.

                        – Anthony Rutledge
                        Oct 3 '16 at 20:04





















                      • That question uses JQuery. I'd much rather see a pure JavaScript question / answer be the standard.

                        – Anthony Rutledge
                        Oct 3 '16 at 20:04



















                      That question uses JQuery. I'd much rather see a pure JavaScript question / answer be the standard.

                      – Anthony Rutledge
                      Oct 3 '16 at 20:04







                      That question uses JQuery. I'd much rather see a pure JavaScript question / answer be the standard.

                      – Anthony Rutledge
                      Oct 3 '16 at 20:04




















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1369004%2fthis-keyword-in-event-methods-when-using-javascript-prototype-object%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Monofisismo

                      Angular Downloading a file using contenturl with Basic Authentication

                      Olmecas