Reputation: 1250
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
Upvotes: 0
Views: 1125
Reputation: 1075815
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());
})();
Upvotes: 4
Reputation: 65873
Because you are using this
within the Sum
function, you need to have an instance of that Object constructed. Using the new
operator to use Sum
as a "constructor function" will accomplish that.
But, then in Sum
you declare this.result
as an instance variable, so you must also refer to it as this.result
in the other spots in the function as well.
Take a look at another post of mine that talks about this
and what it does.
(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 = new Sum();
var s2 = new Sum();
s1.add(10);
s1.add(20);
s2.add(30);
s2.add(5);
console.log(s1.getCurrentSum()); // 30
console.log(s2.getCurrentSum()); // 35
}());
Upvotes: 1