The reason is that when you call foo() you call it in the scope of the window object. This means that inside foo() , this set to window .
So this.taco() is actually window.taco() , which is the same as taco() . In other words, taco() is a global function, so it works like you call it taco() , like window.taco() or like this.taco() when this is window .
If you include taco() as a new object like this, where this set to a new instance of foo and not equal to window , you get the expected error at runtime:
function foo() { var bar = "baz"; this.taco = function() { console.log(this); console.log(bar); }; this.taco(); taco();
Example: http://jsfiddle.net/jfriend00/3LkxU/
If you are confused about the value of this , there are these javascript rules that define the value of this :
If you call a function with new as x = new foo() , then a new instance of foo , and this set to this object inside the function foo() and that the new instance is returned from foo() by default.
If you call some function, as usual, foo() , then this set as a global object, which is in the window browser, or if javascript newer has "strict" mode, then this will be undefined . This is what happened in your original example.
If you call a method with an object reference, for example obj.foo() , then this will be set as an obj object.
If you make a function call using .apply() or .call() , you can specifically determine what this value is for, with the first argument in .apply() or .call() . For example: foo.call(obj) will call the function foo() and set the this pointer to the obj object.
If you are not using any function call (for example, in the global area), then this will be either a global object ( window in the browser) or undefined in strict mode.
As with all of the above rules, this controlled by how the caller calls you, and not how the function / method is defined.
source share