Reputation: 3819
I am trying to extend the function prototype to return a singleton version of a function.
Function.prototype.once = function() {
var called = false, memo;
return function() {
console.log('AP', this);
if (!called) memo = this.apply(this, arguments);
called = true;
return memo;
}
}
The console logs the window object. Why is this != current function? And how to solve this?
Upvotes: 1
Views: 77
Reputation: 239260
You can't "close over" this
, so you need to either resort to the old var self = this
trick (ie, obtain a reference to this
in a variable which can be closed over) or simply bind your function:
return function() {
console.log('AP', this);
if (!called) memo = this.apply(this, arguments);
called = true;
return memo;
}.bind(this);
Upvotes: 7
Reputation: 12420
You have to bind to context on the anonymous function.
Function.prototype.once = function() {
var called = false, memo;
return (function() {
console.log('AP', this);
if (!called) memo = this.apply(this, arguments);
called = true;
return memo;
}).bind(this);
}
Upvotes: 1
Reputation: 339786
Sure, it's possible, but your inner function creates a new context so the this
inside it is not the same as the this
outside.
Just create an external reference to the original function:
Function.prototype.once = function() {
var f = this; // use 'f' in the inner function
...
}
NB: depending on your intent you may also have the same issue with arguments
.
Upvotes: 4