Search code examples
javascriptjqueryobjectinstances

Getting variables value for an object instance using Javascript


I have this code snippet from MDN

I then added a bit of my own code to attach a jQuery click event to a paragraph.

Maybe it is best to show the example:

 function Person(first, last, age, gender, interests) {
      this.name = {
        'first': first,
        'last' : last
      };
      this.age = age;
      this.gen = gender;
      this.int = interests;
      this.nationality = "English";
      this.bio = function() {
        alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.int[0] + ' and ' + this.int[1] + '.');
      };
      this.greeting = function() {
        alert('Hi! I\'m ' + this.name.first + '.');
      };
      this.tt = function() {
        alert('Hi! I\'m ' + this.gen + '.');
      };  
    
      this.init= function() {
      	 $("p").click(function(){
      	  alert('Hi!');	//works fine
          alert('Hi! I\'m ' + this.name.first + '.');//obj.html:34 Uncaught TypeError: Cannot read property 'first' of undefined
         }); 
      };
    
      this.init(); //Bind to the P tag using jQuery click event
    
    }
    var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
    console.log(Person);
    person1.bio();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <p>My first paragraph.</p>
 

So when I click on the P element I get the alert Hi! followed by the uncaught error message.

How do I get the second alert to read, "Hi! I'm Bob"


Solution

  • There are a few ways to solve your problem. this keyword in JavaScript is tricky. The core of your problem is that the this is not what you think it is. See How does the "this" keyword work? for more details.

    1) Cache the this into a variable in pervious scope.

    this.init = function () {
      var self = this;
      $("p").click(function () {
        alert('Hi!');
        alert('Hi! I\'m ' + self.name.first + '.');
      });
    };
    

    2) bind this into the function that's being invoked

    this.init = function () {
      var handleClick = function () {
        alert('Hi!');
        alert('Hi! I\'m ' + self.name.first + '.');
      };
      handleClick = handleClick.bind(this);
      $("p").click(handleClick);
    };