1

I am trying to create a small javascript plugin like this:

function TextShadow(host){
    this.host_id=host;
    this.welcome=function(){alert('welcome to earth')};
    $(function(){
      this.welcome();
      $(this.host_id).html("<p>hello world</p>");
    });
 }

I then call it from an other script like this:

var test=new TextShadow("#sample");

but i get this.welcome is not a function.However if i change the previous code to the following one everything works fine:

   function TextShadow(host){
        this.host_id=host;
        this.welcome=function(){alert('welcome to earth')};
        var gen=this;
        $(function(){
          gen.welcome();
          $(gen.host_id).html("<p>hello world</p>");
        });
   } 

Can someone explain me why the first piece of code doesn't work while the second does?

cssGEEK
  • 994
  • 2
  • 15
  • 38
  • Every function has a `this` and it will depend on **how** you call the function. See http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work – elclanrs Feb 28 '16 at 09:00
  • `this` is no longer referring to the `TextShadow` instance inside the DOM ready function: it is being used as a reference to the window object. – Terry Feb 28 '16 at 09:02

4 Answers4

2

Because the scope changes within JavaScript functions. You can bind the function to set this to the desired value.

function TextShadow(host){
    this.host_id=host;
    this.welcome=function(){alert('welcome to earth')};
    $(function(){
      this.welcome();
      $(this.host_id).html("<p>hello world</p>");
    }.bind(this));
 }

It is even cleaner in ES6 where you can use arrow functions:

$(() => {
  this.welcome();
  $(this.host_id).html("<p>hello world</p>");
});

MDN Scope

Cymen
  • 14,079
  • 4
  • 52
  • 72
1

Because your this changes once you go into the anonymous function. By assigning this to something else: gen, you can still use it in a different function.

Tdelang
  • 1,298
  • 2
  • 12
  • 20
1

You can use bind to set this

function TextShadow(host){
this.host_id=host;
this.welcome=function(){alert('welcome to earth')};
$(function(){
  this.welcome();
  $(this.host_id).html("<p>hello world</p>");
}.bind(this));
}

OR

Use selfor any variable to store this and use self in place of this

function TextShadow(host){
var self=this;
self.host_id=host;
self.welcome=function(){alert('welcome to earth')};
$(function(){
  self.welcome();
  $(self.host_id).html("<p>hello world</p>");
});
}
Flake
  • 1,386
  • 17
  • 31
0

In your first Function Welcome Function Can't be seeing because this Binding of the current execution context .anonymous Function is the current execution context and you try tho access function form anther context