I was expecting the 2nd call of the “taco” function to generate a runtime error since I am not calling it with the “this” keyword:
function foo() {
var bar = "baz";
this.taco = function() {
console.log(bar);
};
this.taco();
taco(); // I expected a runtime error here.
}
foo();
However, it does not.
Here is a fiddle of the same code: http://jsfiddle.net/phillipkregg/gdFxU/226/
Is JavaScript using some type of implicit context management here?
Just curious, thanks!
The reason is that when you call
foo(), you are invoking it in the scope of thewindowobject. That means that inside offoo(), the value ofthisis set towindow.Thus,
this.taco()is actuallywindow.taco()which is the same astaco(). In other words,taco()is a global function so it works either way you call it astaco(), aswindow.taco()or asthis.taco()whenthisiswindow.If you involve
taco()as a new object like this wherethisis set to a new instance offooand is not equal towindow, then you get the expected run-time error:Example: http://jsfiddle.net/jfriend00/3LkxU/
If you are confused about the value of
this, there are these javascript rules that determine the value ofthis:If you call a function with
newlikex = new foo(), then a new instance offoois created and the value ofthisis set to that object inside thefoo()function and that new instance is returned fromfoo()by default.If you call any function normally like
foo(), then the value ofthisis set to be the global object which in a browser iswindowor if in javascript’s newer “strict” mode, thenthiswill beundefined. This is what was happening in your original example.If you call a method with an object reference like
obj.foo(), thenthiswill be set to be theobjobject.If you make a function call with
.apply()or.call(), then you can specifically control what the value ofthisis set to with the first argument to.apply()or.call(). For example:foo.call(obj)would call thefoo()function and set thethispointer to theobjobject.If you are not in any function call (e.g. at the global scope), then
thiswill be either the Global object (windowin a browser) orundefinedin strict mode.As in all of the above rules,
thisis controlled by how the caller calls you, not how the function/method is defined.