I hope you enjoyed the link I provided in Solution 2. Now, let's see what's going on with your simple case. One of the possible solutions would be this:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
this.calculateBonus = function() {
alert(this.name);
return (this.salary + 1000);
}
this.calculateBonus();
}
Let's assume you are using strict mode in all cases. Non-strict behavior is too confusing to use during development. In your original code,
alert
would show the
window
object, which is plain wrong (or, those obsolete wrong decisions!) and hard to recognize what is that. I output
this.name
only to show some evidence that this is correct "this". (In the style of the sayings by Rabbit from Miln's Winnie-the-Pooh: "'this' can be different!". :-))
Of course, in this particular piece of code, making
calculateBonus
would be utterly impractical, because this is not what you meant to do; you probably did not want to expose this function to the object users. I'm pretty much sure that you knew the practical solution; only it would be not useful to uncover the "mystery" of "this". So, just in case:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
calculateBonus = function(owner) {
alert(owner.name);
return (owner.salary + 1000);
}
calculateBonus(this);
}
Now, let's say, you want to use the closure. Great! This is actually much better idea than using properties. I hope the solution would be obvious:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
var name = this.name;
var salary = this.salary;
var calculateBonus = function() {
alert(name);
return (salary + 1000);
}
calculateBonus();
}
Let's make another step. Why would we need "calculateBonus" at all. Get rid of it:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
var name = this.name;
var salary = this.salary;
(function() {
alert(name);
return (salary + 1000);
})();
}
Much better, isn't it? Please see
Pluralitas non est ponenda sine necessitate, see also:
Occam's razor — Wikipedia, the free encyclopedia,
Immediately-invoked function expression — Wikipedia, the free encyclopedia.
Another variant combining some of the above:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
var owner = this;
(function() {
alert(owner.name);
return (owner.salary + 1000);
})();
}
Now, I want to introduce another exciting feature of strict mode. It can help you by taking out false freedom of using the constructors. Try this:
function ConstructorInFact() {
this.A = 13;
return 14;
}
var a = new ConstructorInFact();
var b = ConstructorInFact();
I hope that you can see how this code is silly. If this is used as a constructor (
a
),
return 14
is not used. If it is as not a constructor call (
b
), "this" is pointless. However, all this will work in non-strict mode. Some say it's nice, but it won't detect the silliness of this code. Switch to the strict mode and, for a first attempt, comment out the last line (
b
). Still, it will work.
Uncomment the last line. In want line the problem will be detected. Surprise: in the line "this.A =…": "this is undefined". Note that the problem only exists if the last line is there.
Wait a minute! Isn't JavaScript an interpreter? No, it is not a pure interpreter. The script is first lexically analyzed. Another surprise? :-)
—SA