7

Can anyone explain why do I get different values of self and this? Where self is a reference to this.

function Parent(){
   var self = this;
   this.func = function(){
      // self.a is undefined
      // this.a is 'Test'
      console.log(self.a, this.a);
   }
}

function Child(x){
   this.a = x;
}

Child.prototype.__proto__ = new Parent;
var ch = new Child('Test');
ch.func();

I've been using self on project and it's my first time to have this issue.

Kevin
  • 492
  • 5
  • 14
  • self and this are no longer referring to the same object. The following link may be helpful : http://stackoverflow.com/questions/962033/what-underlies-this-javascript-idiom-var-self-this – Chetter Hummin Feb 25 '13 at 09:31
  • ô the joy of javascript call context ! – benzonico Feb 25 '13 at 09:32
  • In `func`, it seems like `self` points to the `Parent`, but `this` points to the `Child`. – Blender Feb 25 '13 at 09:33
  • Thanks for the answers. This is why I like javascript, very different. Now I need to be more careful on nested callbacks. – Kevin Feb 25 '13 at 10:41

4 Answers4

9

This is because self refers to an instance of Parent, but only instances of Child have an a property.

function Parent(){
   var self = this; // this is an instance of Parent
   this.func = function(){
      console.log(self.a, this.a);
   }
}

function Child(x){
    this.a = x; // Instances of Child have an `a` property
}

Child.prototype.__proto__ = new Parent;
var ch = new Child('Test');

ch.func(); // Method called in context of instance of Child

So when you call func on an instance of Child, this refers to that instance. That's why this.a gives you the correct value inside func.

James Allardice
  • 156,021
  • 21
  • 318
  • 304
1

Within func, this refers to an instance of Child.

Child.prototype.__proto__ = new Parent;

The prototype of Child is set to an instance of Parent. So when ch.func() is invoked, func() is on the prototype chain of Child, but is invoked in the context of ch which is an instance of Child

self is still referring to the instance of Parent which does not have an attribute a

To further illustrate:

var p = new Parent();

// this.a is undefined because this is an instance of Parent
p.func(); // undefined undefined
Aditya Manohar
  • 1,924
  • 1
  • 15
  • 19
0

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log("outer func1:  this.foo = " + this.foo); //bar
        console.log("outer func2:  self.foo = " + self.foo); //bar
        (function() {
            console.log("inner func3:  this.foo = " + this.foo); //undefind
            console.log("inner func4:  self.foo = " + self.foo);//bar
        }());
    }
};
myObject.func();
Avinash Maurya
  • 252
  • 2
  • 4
  • 1
    In the inner function, though, this no longer refers to myObject. As a result, this.foo is undefined in the inner function, whereas the reference to the local variable self remains in scope and is accessible there. – Avinash Maurya Sep 13 '18 at 01:48
0

function Foo() {
  this.bar = 'bar';
  return this;
}
Foo.prototype.test = function(){return 1;}



function Bar() {
  this.bro = 'bro';
  return this;
}
Bar.prototype.test2 = function(){return 2;}

function Cool2() {
  Foo.call(this);
  Bar.call(this);

  return this;
}
//console.log(Object.create(Bar.prototype));
var combine = Object.create(Foo.prototype);
//console.log(combine);

$.extend(combine, Object.create(Bar.prototype));
$.extend(combine, Object.create(Foo.prototype));

Cool2.prototype = Object.create(combine);
//Cool2.prototype.constructor = Cool2;

var cool = new Cool2();
 

console.log(cool.test()); // 1
console.log(cool.test2()); //2
console.log(cool.brow) //bro
console.log(cool.bar) //bar
console.log(cool instanceof Foo); //true
console.log(cool instanceof Bar); //false


 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
Avinash Maurya
  • 252
  • 2
  • 4