Ad

Javascript: Assign Function To A Variable Fills Variable With Undefined

- 1 answer

It's kinda basic, but its giving me some headaches:

I'm assigning a function to a variable, then I call a function inside the first function from the variable.

When I assign the function to the variable its filled with undefined, so when I call the inner function I get the error:

Uncaught TypeError: Cannot read property 'add' of undefined

This is the code I'm working on:

(function () {

  function Sum() {

    this.result = 0;

    this.getCurrentSum = function getCurrentSum() {
      return this.result;
    }

    this.add = function add(add_number) {
      this.result += add_number;
    }

  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());

}());

I can change the code in the Sum function, but I can't change the rest of the code

Ad

Answer

It looks like you want Sum to be a constructor function. You call constructor functions via new, not directly. So:

var s1 = new Sum();
var s2 = new Sum();

The reason you were getting undefined in s1 and s2 without new is that Sum doesn't do return x anywhere, so the result of calling it is the value undefined. But when you use new, the result of the new expression is the object that was created.

FWIW, there's another problem with Sum: You're missing out this. in a couple of places (also a couple of semicolons, though Automatic Semicolon Insertion will add them for you):

function Sum() {
  this.result = 0;

  this.getCurrentSum = function getCurrentSum() {
    return this.result;
// −−−−−−−−^^^^^
  };

  this.add = function add(add_number) {
    this.result += add_number;
// −^^^^^
  };
}

JavaScript isn't like Java or C#, this. isn't optional.


In a comment you've asked:

wat if I can change the Sum function or anything inside the function but I can't change the var s1 = Sum();calling?

In that case, you'd make Sum a builder function and have it return an object, like this:

function Sum() {
  return {
    result: 0,
    getCurrentSum: function getCurrentSum() {
      return this.result;
    },
    add: function add(add_number) {
      this.result += add_number;
    }
  };
}

Live Example:

(function () {

  function Sum() {
    return {
      result: 0,
      getCurrentSum: function getCurrentSum() {
        return this.result;
      },
      add: function add(add_number) {
        this.result += add_number;
      }
    };
  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());
})();

Normally a builder function wouldn't start with a capital letter (that's essentially reserved for constructor functions), so it would have a name like createSum or buildSum or similar.

That version of Sum is written with ES5-level syntax (actually it's even ES3-level). In ES2015+ it could be a bit more concise:

// ES2015+ using method syntax
function Sum() {
  return {
    result: 0,
    getCurrentSum() {
      return this.result;
    },
    add(add_number) {
      this.result += add_number;
    }
  };
}

Live Example:

(function () {

  // ES2015+ using method syntax
  function Sum() {
    return {
      result: 0,
      getCurrentSum() {
        return this.result;
      },
      add(add_number) {
        this.result += add_number;
      }
    };
  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());
})();

Ad
source: stackoverflow.com
Ad