does javascript's this object refer to newly created object in the way i think

So, when we create constructor function for creating new object the new keyword does 3 things I'am going to explain it but please correct me if I'am wrong i want to be sure I'am correct

first i will create a constructor function

function ObjectCreate(){
    this.a = "a";
    this.b = "b";

    ObjectCreate.prototype.show = function(){
        alert(this.a+" "+this.b);
    }
}

obj1 = new ObjectCreate();

now the first thing new keyword does is create new object and set its secret link to its constructor's prototype and pass it to the constructor function where now the this can refer to it and please note this does not refer to obj1 at this point because once constructor finished creating object only then it returns the newly created object to obj1 variable. i ask this question because some people say that this refer to the obj1 object in this case. so am i right here.

Answers:

Answer

In this example, during constructor invocation, obj1 is undefined. Value is assigned to obj1 variable after ObjectCreate function returns.

You can check yourself:

function ObjectCreate(){
    this.a = "a";
    this.b = "b";

    alert(obj1); // yields "undefined"
    ObjectCreate.prototype.show = function(){
        alert(this.a+" "+this.b);
    }
}

var obj1 = new ObjectCreate(); // note "var"
Answer

Your phrasing is a bit confusing, but I'll do my best. First, you should note that your curly braces are a bit off. Your code should look like this:

function ObjectCreate(){
   this.a = "a";
   this.b = "b";
}

ObjectCreate.prototype.show = function(){
     alert(this.a+" "+this.b);
}

obj1 = new ObjectCreate();

You need to define your constructor, then attach things to its prototype.

When you call the constructor, the this keyword does basically refer to the new object being created. This is important because, for example, you could write a constructor like:

function ObjectCreate(x,y){
   this.a = x*x;
   this.b = y*x+4;
}
obj1 = new ObjectCreate(10,20);

Here, as in all constructors, this refers to the instance being created (obj1, in this case).

I think you suggested that this refers to the object's prototype, but that would make this.a and this.b static variables, which would be useless in a constructor like the one here, since every time you initialized a new object you would change the vale of this.a and this.b for all previously existing objects, and that just isn't useful.

I hope that answered your question. If not, please go ahead and leave comments for further clarification.

Answer

It seems nobody mentioned that this refers to the invoking object.

window.sayHi=function(){
  console.log(this.name);
}
window.name="Window"
window.sayHi();//=Window

var obj={
  name:"obj"
}
obj.fn=window.sayHi;

obj.fn();//=obj

The code above shows that when passing functions around the this context will change. If you don't want that then you can pass a closure instead of the function or use call, apply or bind:

//closure example
obj.fn=(function(w){//w is available because the returned function is a closure
  return function(){
    w.sayHi();
  }
}(window));

obj.fn();//=Window
//using call
obj.fn.call(window);//=Window
//using apply
obj.fn.apply(window);//=Window
//using bind
var boundFn=obj.fn.bind(window);
boundFn();//=Window

That was when you pass a function as a parameter on another object. When you use constructor functions then this within the function body will refer to the object to be created.

But when you pass around it's functions it may not be:

var obj={
  name:"obj"
}
var Test=function(){
  this.name="Test";
}
Test.prototype.sayHi=function(){
  console.log(this.name);
};

var t=new Test();
obj.fn=t.sayHi
t.sayHi();//=Test
obj.fn();//=obj

This is a pitfall most people fall in when passing object instance functions to setTimeout or event handlers:

someButton.onclick=t.sayHi;//when button is clicked this will be the button clicked
setTimeout(t.sayHi,100);//when sayHi is executed 'this' will be window

To answer your question about obj1 existing within the constructor function's body; I'd say no (not in Firefox at least). I don't have a link to the specs but obj1 would be set to this when the constructor function returns:

//clean up window.t
delete window.t;
var Test=function(){
  this.name="Test";
  console.log("and window.t is:",window.t);//undefined
}
Test.prototype.sayHi=function(){
  console.log(this.name);
};

window.t=new Test();

More on constructor functions, prototype, inheritance, overriding and calling super here.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.