'this' - undefined in JavaScript class methods

I am new to JavaScript. New, as far as I really did with it, is to modify existing code and write small jQuery snippets.

Now I'm trying to write a "class" with attributes and methods, but I'm having problems with methods. My code is:

function Request(destination, stay_open) { this.state = "ready"; this.xhr = null; this.destination = destination; this.stay_open = stay_open; this.open = function(data) { this.xhr = $.ajax({ url: destination, success: this.handle_response, error: this.handle_failure, timeout: 100000000, data: data, dataType: 'json', }); }; /* snip... */ } Request.prototype.start = function() { if( this.stay_open == true ) { this.open({msg: 'listen'}); } else { } }; //all console.log omitted 

The problem is in Request.prototype.start , this is undefined, and therefore the if statement evaluates to false. What am I doing wrong here?

+41
javascript prototype class
Oct 25 '10 at 3:48
source share
3 answers

How do you call the start function?

This should work ( new is the key)

 var o = new Request(destination, stay_open); o.start(); 

If you call it as Request.prototype.start() , this will refer to the global context ( window in browsers).

Also, if this is undefined, this leads to an error. The if value is not evaluated as false.

Update : this object is not set based on the declaration, but by a call. This means that if you assign a property of a function to a variable of type x = o.start and call x() , this inside the beginning no longer refers to o . This happens when you do setTimeout . To make it work, do the following:

  var o = new Request(...); setTimeout(function() { o.start(); }, 1000); 
+43
Oct 25 2018-10-10T00:
source share

JavaScript OOP is a little scared (or a lot), and it takes some getting used to. This is the first thing you need to keep in mind that there are no classes and thinking in terms of classes can touch you. And in order to use the method attached to the constructor (the equivalent of JavaScript class definitions), you need to instantiate the object. For example:

 Ninja = function (name) { this.name = name; }; aNinja = new Ninja('foxy'); aNinja.name; //-> 'foxy' enemyNinja = new Ninja('boggis'); enemyNinja.name; //=> 'boggis' 

Note that Ninja instances have the same properties, but aNinja cannot access the enemyNinja properties. (This part should be very simple / simple). When you start adding material to prototype , you are a little different:

 Ninja.prototype.jump = function () { return this.name + ' jumped!'; }; Ninja.prototype.jump(); //-> Error. aNinja.jump(); //-> 'foxy jumped!' enemyNinja.jump(); //-> 'boggis jumped!' 

Calling this directly will lead to an error, because this only points to the correct object (your "class") when creating the constructor instance (otherwise it points to the global window object in the browser)

+14
Oct 25 2018-10-10T00:
source share

In ES2015, aka ES6, a class is syntactic sugar for functions .

If you want to force a context for this , you can use the bind() method. As @chetan pointed out, you can also set context when called! See an example below:

 class Form extends React.Component { constructor() { super(); } handleChange(e) { switch (e.target.id) { case 'owner': this.setState({owner: e.target.value}); break; default: } } render() { return ( <form onSubmit={this.handleNewCodeBlock}> <p>Owner:</p> <input onChange={this.handleChange.bind(this)} /> </form> ); } } 

Here we forced the context inside handleChange() to Form .

+3
Mar 12 '16 at 20:21
source share



All Articles