user1829716
user1829716

Reputation: 307

References & Scope in anonymous functions

I'm new to object oriented javascript. I have a simple class, what seems to be in JavaScript a function. My class has two members and some methods:

function WebApp() {
  //members
  this.webSocket = null;
  this.workdata = null;

  //constructor
  $( 'document' ).ready(function() {
    $('#wait').show();
    this.initializeWebsocket();
  });

  this.getURLParameter = function(sParam)
  {
    //retrieves GET-PARAMETER
  }

  this.initializeWebsocket = function() {
        //websocket connection
      }
}
var app = new WebApp();

When the anonymous function for document.ready runs I get the following error: Uncaught ReferenceError: initializeWebsocket is not defined

I understand the exception because this is in this scope document. I am able to call the function on this way:

app.initializeWebsocket();

But on this way I cannot instantiate more than one object of WebApp. Is it possible to pass the this- webappinstance as a reference into the anonymous function?

Upvotes: 0

Views: 262

Answers (5)

Axel Amthor
Axel Amthor

Reputation: 11096

In this code lines:

function WebApp() {
  //members
  this.webSocket = null;
  this.workdata = null;

  //constructor
  $( 'document' ).ready(function() {
    $('#wait').show();
    this.initializeWebsocket();
  });

The keyword this is referencing the enclosing object, which is $('document') in this case. In order to reference the outer object (WebApp), just use a object variable:

function WebApp() {
  //members
  this.webSocket = null;
  this.workdata = null;

  // reference to me
  var that = this;

  //constructor
  $( 'document' ).ready(function() {
    $('#wait').show();
    that.initializeWebsocket();
  });

The scope of variables like that and their current value will be set in the context of the call to $( 'document' ).ready during runtime in JS.

Upvotes: 0

Furquan Khan
Furquan Khan

Reputation: 1594

Here is the trick

 function WebApp() {
  //members
  this.webSocket = null;
  this.workdata = null;

  $('#wait').show();
  this.initializeWebsocket();

  this.getURLParameter = function(sParam)
  {
      //retrieves GET-PARAMETER
  }

  this.initializeWebsocket = function() {
       //websocket connection
  }
}

$(function() {
    var app = new WebApp();
});

Upvotes: 0

Mjh
Mjh

Reputation: 2945

The core of the problem is the following lines of your code:

$( 'document' ).ready(function() {
    $('#wait').show();
    this.initializeWebsocket();
  });

this refers to anonymous function in ready(). It does not refer to the actual object you've created. There's an easy way to fix it - alter the scope of the anonymous function.

Even though you should not really use $(document).ready in your constructor, easiest way to remedy your issue would be to use $.proxy. The code you need to alter and add would be:

$(document).ready($.proxy(function() {
    $('#wait').show();
    this.initializeWebsocket();
  }, this));

Upvotes: 1

Sandeep Nayak
Sandeep Nayak

Reputation: 4757

You shpuld save the reference to this outside of your anonymous function like so:

function WebApp() {
  var self = this; // Reference to this is in variable called self.
  //members
  this.webSocket = null;
  this.workdata = null;

  //constructor
  $( 'document' ).ready(function() {
    $('#wait').show();
    self.initializeWebsocket(); // Here this refers to different scope.. so use self
  });

  this.getURLParameter = function(sParam)
  {
    //retrieves GET-PARAMETER
  }

  this.initializeWebsocket = function() {
        //websocket connection
    console.log("inside websocket")
      }
}
var app = new WebApp();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Upvotes: 1

Bas Slagter
Bas Slagter

Reputation: 9929

For starters you should wrap the initial call in $('document').ready() and not inside your class. Secondly; 'this' inside the ready function now points to the callback of the ready call and that does indeed not have the initializeWebsocket method on it. You could go with a var that = this solutionn but in this case you are saved by pulling out the document ready.

$(function() {
    var app = new WebApp();
});

function WebApp() {
  //members
  this.webSocket = null;
  this.workdata = null;

  $('#wait').show();
  this.initializeWebsocket();

  this.getURLParameter = function(sParam)
  {
      //retrieves GET-PARAMETER
  }

  this.initializeWebsocket = function() {
       //websocket connection
  }
}

Note that I also pulled the initialization to the top for readability. This works due to hoisting. I also used the shorthand version of the document ready syntax.

Upvotes: 2

Related Questions