I have the following code:
var foo = function () {
foo = this;
foo.boo = function () {
console.log("boo");
}
}
var bar = new foo().boo();
var baz = new foo().boo();
This code executes the first creation of an instance of foo
, but fails at the second with the following output:
boo
/Users/BaranSkistad/Code/example.js:9
var baz = new foo().boo();
^
TypeError: foo is not a constructor
at Object.<anonymous> (/Users/BaranSkistad/Code/example.js:9:11)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:578:3
Why is this script failing? I know it has something to do with setting foo to this
on line 2, instead of just using this
, but why is it problematic?
var foo = function () {
self = this;
self.boo = function () {
console.log("boo");
}
}
var bar = new foo().boo();
var baz = new foo().boo();
If I set self
to equal this
, it passes, why is this so?
The problem is in the following line
foo = this;
The above line misses the variable declaration. So foo
will refer to the global variable foo
which is a constructor.When you call the function first time the line executes and foo
is changed to this
(instance of the foo
)
In the second case the code also creates a global variable self
which will be equal to this
. But in that case it will not change constructor because the names are different.
The solution to this is to make foo
a local variable by using let
(or const/var
).
var foo = function () {
let foo = this;
foo.boo = function () {
console.log("boo");
}
}
var bar = new foo().boo();
var baz = new foo().boo();