That's because this with normal functions is set by how the function is called, not where it's defined. (ECMAScript2015's "arrow" functions are different, they inherit this from where they're created, not how they're called.)
You have a couple of options:
1) Use Function#bind to create a new function that, when called, will call your original function with the correct this:
var foo = {
bar: function() {
return this.baz;
},
baz: 1
};
(function() {
snippet.log(typeof arguments[0]());
})(foo.bar.bind(foo));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
2) Use your own wrapper function:
var foo = {
bar: function() {
return this.baz;
},
baz: 1
};
(function() {
snippet.log(typeof arguments[0]());
})(function() {
return foo.bar.apply(foo, arguments);
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>