1

I am trying to grasp the concepts of Javascript through online video courses, where I came upon this example below. https://www.youtube.com/watch?v=9oi0NY8Pen8

The instructor used this example first

var carlike = function(obj, loc) {
  obj.loc = loc;
  obj.move = function() {
    this.loc++;
  };
  return obj;
};

var amy = carlike({}, 1);
amy.move();

and then changed the carlike function to

var carlike = function(obj, loc) {
  obj.loc = loc;
  obj.move = function() {
    obj.loc++;
  };
  return obj;
};

Saying the Instead of referring to the parameter this which gets bound to a new value each time move is invoked we can use obj

How is this getting bound to new value. How can using obj prevent this.

Saad
  • 1,636
  • 1
  • 20
  • 24
  • What is the change? Both the codes look the same to me – thefourtheye Apr 04 '15 at 05:17
  • 1
    The value of `this` in any `function` is determined when and by how it's called, not by how it's defined. [How does the “this” keyword work?](http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Jonathan Lonowski Apr 04 '15 at 05:24
  • @JonathanLonowski—mod [*bind*](http://ecma-international.org/ecma-262/5.1/#sec-15.3.4.5). ;-) – RobG Apr 04 '15 at 05:40

3 Answers3

3

When you call amy.move(), within move the "variable" this gets the value of amy, which is an object. If move contains the code this.loc++, then the value of the property amy.loc will be incremented.

You can, however, invoke that function in other ways. For example:

var func = amy.move; // copies reference to function into variable func
func();              // "this" is unspecified

In the above case, because this is unspecified, it defaults to window (in non-strict mode) or undefined (in strict mode).

Or:

var bill = { loc: 4 };
amy.move.call(bill); // "this" is bill, not amy

On the other hand, if the move function contains the code obj.loc++, then it will always increment the loc of same object: namely, the one that was passed to carlike when this instance of move was created:

var amy = carlike({}, 1);
var bill = { loc: 4 };
amy.move.call(bill); // "this" is bill, not amy
console.log(amy.loc); // prints 2
console.log(bill.loc); // prints 4

The move function, when created, becomes a closure on the local variable obj within carlike.

In this small example, there is no particular benefit to doing this, but closures are a powerful technique in general.

radiaph
  • 3,711
  • 1
  • 14
  • 19
2

When you call the move function as:

amy.move();

then you are setting the value of this within move to amy. If you do:

var b = amy.move;
b();

you are now calling the function without setting this, so it defaults to the global/window object in non–strict mode, and is undefined in strict mode. By using:

  obj.loc = loc;
  obj.move = function() {
    obj.loc++;
  };

then the function keeps a reference to obj via a closure, so no matter how the function is called, obj always references the object originally passed to carlike.

RobG
  • 124,520
  • 28
  • 153
  • 188
1

Since this in javascript is decided at function invocation. Using it inside methods causes unwanted bugs. You may not realize this if you call the function yourself using amy.move().

Ex:

var carlike = function(obj, loc) {
  obj.loc = loc;
  obj.move = function() {
    console.log(this);
    this.loc++;
  };
  return obj;
};

var amy = carlike({}, 1);
amy.move(); => this will corresponds to object which are returned from constructor.

setTimeout(amy.move, 1000) => this will corresponds to window 

Since the constructor is returning the object, its safe to use obj inside the function amy.

Ref: this in javascript

Sriharsha
  • 2,120
  • 1
  • 14
  • 19