Home The 'this' context is lost during assignment, but not quite?
Reply: 1

The 'this' context is lost during assignment, but not quite?

Thomas An
1#
Thomas An Published in 2017-11-13 05:39:55Z

This question already has an answer here:

  • How does the “this” keyword work? 19 answers

In the following example there is a simple object. Two instances were created for me to test variable scope.

When test1a (and test2a) is assigned to the method ShowNum it behaves identically as when calling oneObj.ShowNum() by itself. However, when test1b is assigned to the method ShowNum2, then it behaves differently than calling oneObj.ShowNum2() directly.

This is a little puzzling to me because it seems that the 'this' scope is being lost during assignment, but at the same time it is NOT lost because 'num' is still found (and num is as unique to the object instance as this.num2 is).

What is the esoteric explanation for this behavior ?

function TestObject ()
{
    var num   = 25;
    this.num2 = 50;
    this.ShowNum  = function () {return num;}
    this.ShowNum2 = function () {return this.num2;}
    this.SetNum   = function (newnum) {num = newnum;}
}
var oneObj = new TestObject();
var twoObj = new TestObject(); twoObj.SetNum(100); twoObj.num2 = -12;

var test1a = oneObj.ShowNum;
var test1b = oneObj.ShowNum2;
var test2a = twoObj.ShowNum;
var test2b = twoObj.ShowNum2;

console.log(oneObj.ShowNum());
console.log(oneObj.ShowNum2());
console.log(test1a());
console.log(test1b());

console.log(twoObj.ShowNum());
console.log(twoObj.ShowNum2());
console.log(test2a());
console.log(test2b());

Result:

25
50
25
undefined

100
-12
100
undefined

EDIT: This question does seem like a variant of the one -->here as pointed out by the replies. My instinctive expectation was that var test1b = oneObj.ShowNum; should imply var test1b = oneObj.ShowNum2.bind(oneObj); making it for consistent behavior across languages (as Mahesha999 mentioned with the following)

The this keyword behaves differently in JavaScript compared to other language. In Object Oriented languages, the this keyword refers to the current instance of the class. In JavaScript the value of this is determined mostly by the invocation context of function (context.function()) and where it is called.

Right now I don't feel like pressing further and I consider this matter closed.

Vivek Doshi
2#
Vivek Doshi Reply to 2017-11-13 06:05:03Z

Reason :

// you are not assigning the whole object , but just passing refernce to the function
var test1a = oneObj.ShowNum;
var test1b = oneObj.ShowNum2; // so from here it will lose the context of this

test1a is like

function () {return num;}

and test1b is like

function () {return this.num2;}

Here, if you directly assign the function, here this is not pointing to parent function anymore. as you have just assigned the function

You can check that by just putting console.log inside like,

this.ShowNum2 = function () { console.log(this); return this.num2;}

Debugging : Run the below code snippet and you will get idea :

function TestObject ()
{
    var num   = 25;
    this.num2 = 50;
    this.ShowNum  = function () {return num;}
    this.ShowNum2 = function () { console.log(this); return this.num2;}
    this.SetNum   = function (newnum) {num = newnum;}
}
var oneObj = new TestObject();
var twoObj = new TestObject(); twoObj.SetNum(100); twoObj.num2 = -12;

var test1a = oneObj.ShowNum;
var test1b = oneObj.ShowNum2;
var test2a = twoObj.ShowNum;
var test2b = twoObj.ShowNum2;

console.log(oneObj.ShowNum());
console.log(oneObj.ShowNum2());
console.log(test1a());
console.log(test1b());

console.log(twoObj.ShowNum());
console.log(twoObj.ShowNum2());
console.log(test2a());
console.log(test2b());

Solution :

//.bind(parent_object);

var test1b = oneObj.ShowNum2.bind(oneObj);
var test2b = twoObj.ShowNum2.bind(twoObj);

function TestObject ()
{
    var num   = 25;
    this.num2 = 50;
    this.ShowNum  = function () {return num;}
    this.ShowNum2 = function () {return this.num2;}
    this.SetNum   = function (newnum) {num = newnum;}
}
var oneObj = new TestObject();
var twoObj = new TestObject(); twoObj.SetNum(100); twoObj.num2 = -12;

var test1a = oneObj.ShowNum;
var test1b = oneObj.ShowNum2.bind(oneObj);
var test2a = twoObj.ShowNum;
var test2b = twoObj.ShowNum2.bind(twoObj);

console.log(oneObj.ShowNum());
console.log(oneObj.ShowNum2());
console.log(test1a());
console.log(test1b());

console.log(twoObj.ShowNum());
console.log(twoObj.ShowNum2());
console.log(test2a());
console.log(test2b());

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.303626 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO