2

For the below code snippet i am expecting the answer as "number" but i am getting it as "undefined". Can anyone please help me here to find out why its returning "undefined" ?

var foo = {
    bar: function () {
        return this.baz;
    },
    baz: 1
};

(function () {
    return typeof arguments[0](); //this will return "undefined"
})(foo.bar);

If i do typeof foo.bar(), then it will give me the expected answer as "number".

Thanks in advance.

1 Answer 1

3

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>

Sign up to request clarification or add additional context in comments.

6 Comments

I was about to answer the same var foo = { bar: function () { console.log(this); return this.baz; }.bind(foo), baz: 1 }; (function () { return typeof arguments[0](); }(foo.bar));. Anyway +1 for nice explanation
Thanks Crowder and Tushar. But second way still returns "undefined" isn't it?
@Parashuram return foo.bar.apply(foo, arguments); use foo instead of this
TJ is there a reason you have used arguments in (function() { return foo.bar.apply(foo, arguments); })
@Tushar: Just to pass on all the arguments given to it. Thanks for the this/foo fix, I'd forgotten we were trying to preserve that! :-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.