1

I'm trying hard to understand basic concepts of javascript. The code below seems to be working fine if I use only "gear += 1" in line 8 below, but I cannot understand why is this not working when I'm using "this.gear += 1". It gives result as NaN. Thank you.

(function bike(speed, tank, gear) {
  var i = {};
  i.speed = speed;
  i.tank = tank;
  i.gear = gear;
  i.addgear = (function() { 
    // works fine with "return gear+= 1" Why not with "this"?     
    return this.gear += 1;  
 })();

 console.log("mybike", i);   
})(120, 12, 5);   
Geuis
  • 37,442
  • 53
  • 145
  • 213
  • Why do you expect `this` to work in the first place? None of this looks class-y (including pre-ES5 JS OOP), so I'm not quite sure what to explain. – Soron Mar 01 '18 at 19:19
  • 3
    Your closure for i.addgear is executing immediately. – Geuis Mar 01 '18 at 19:21
  • 1
    @EthanKaminski - actually, it makes perfect sense for `addgear`'s `this` to be `i`... except that the OP is, perhaps unintentionally, assigning the result of an [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) to `addgear` rather than an anonymous function. – JDB still remembers Monica Mar 01 '18 at 19:23
  • @JDB - Yes, that was exactly my point. addgear's this should act as i... but it doesn't... Can you tell why? – Rohit Verma Mar 01 '18 at 19:28
  • @Rohit - Geuis already told you. Read that article I linked to in my comment. Your assigning the result of executing the function, rather than the actual function. You're very close to a working solution, you're just overdoing it: `i.addgear = (function() { // works fine with "return gear+= 1" Why not with "this"? return this.gear += 1; });` – JDB still remembers Monica Mar 01 '18 at 19:32
  • 1
    For those voting that this was a duplicate of the standard "how does `this` work" post... that wasn't what this question asked, not directly, nor does the answer there really help explain either what's wrong with the code supplied or how to get the desired behavior. – Scott Sauyet Mar 01 '18 at 19:50

1 Answers1

1

There are many ways to achieve what you're looking for, including the class keyword from ES2015 and up or the prototype system that underlies it. Here's a very simple sample:

function bike(speed, tank, gear) {
  return {speed, tank, gear, addGear: function() {return this.gear += 1}}
}

const myBike = bike(120, 12, 5)
console.log(myBike);
myBike.addGear();
console.log(myBike)

Yours doesn't work for several reasons. First of all, you never return anything out of your outermost function. Secondly, you create and immediately execute a function whose output then becomes your addGear value. The simplest fix to your code would be something like this:

function bike(speed, tank, gear) {
  var i = {};
  i.speed = speed;
  i.tank = tank;
  i.gear = gear;
  i.addgear = function() { 
    return this.gear += 1;  
  };
  return i;
}

That would be equivalent to what I wrote above.

Scott Sauyet
  • 37,179
  • 4
  • 36
  • 82