Reputation: 4582
I ran into a problem with my javascript code.
I have a class MyClass
and added function myFunction
to its prototype.
MyClass.prototype.myFunction = function(file){
if(some condition){
fs.exists("./" + file, function(exists){
if(exists)
console.log(this.someValue);
/* lot of other code */
else
/* do something else */
});
}else{
/* do something */
}
}
My problem is the scoping of this.someValue
(as an example I want to just print it).
Everytime exists
equals true
the console logs undefined
but it is not.
If I would print it outside of fs.exists()
then it has a value so I guess it is a scoping problem.
How can I access this.someValue
in this sample?
Thanks in advance!
Upvotes: 2
Views: 145
Reputation: 23047
As this
- is keyword that is defined by scope of function and responds to owner or caller of a function. So you might store its pointer in another variable:
MyClass.prototype.myFunction = function(file) {
if(some condition) {
var self = this; // create variable with pointer to 'this'
fs.exists("./" + file, function(exists) {
if(exists) {
console.log(self.someValue); // we can access it to parent scope variables
/* lot of other code */
} else {
/* do something else */
}
});
} else {
/* do something */
}
}
As well check out this brilliant topic: How does the "this" keyword work?
Upvotes: 2
Reputation: 135197
You have to .bind
your inner function
MyClass.prototype.myFunction = function(file){
if(some condition){
fs.exists("./" + file, function(exists){
if(exists)
console.log(this.someValue);
/* lot of other code */
else
/* do something else */
}.bind(this));
}else{
/* do something */
}
}
This can be rewritten to be cleaner
MyClass.prototype.myFunction = function myFunction(file){
if(some condition){
fs.exists("./" + file, this.doSomething.bind(this));
}
else{
// do something else
}
}
MyClass.prototype.doSomething = function doSomething(exists) {
if(exists) {
console.log(this.someValue);
// lot of other code
}
else {
// do something else
}
}
I personally like this solution because it allows you to maintain excellent code composition and prevents you from nesting function(){ function(){ function(){ ... }}}
. It also prevents you from having a bunch of var that = this;
or var self = this;
variables floating around having you wonder which scope is which.
.bind
is slower, yes, but as minitech points out, it's certainly not going to be your bottleneck when compared to file access.
Upvotes: 4
Reputation: 418
MyClass.prototype.myFunction = function(file){
var that = this;
// some lines of code later...
console.log(that.someValue);
}
Upvotes: 3