0

In this example, I am passing foo.bar to an IIFE, which returns executing 1st-argument. I am passing a function which gets executed, returning this (pointing to window).

So, the return is stored in a which should be window. Then, why it is returning me the argument itself?

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

var a = (function(){
  console.log("window?", this===window);
  return arguments[0](); 
})(foo.bar);

console.log("a", a);
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
Deadpool
  • 6,416
  • 5
  • 32
  • 64
  • Is there a real world use for this because I wouldn't write any code like this at all. You've just found the most confusing possible way to call a function. Also, is this strict mode or sloppy mode? – jfriend00 May 29 '21 at 02:43
  • @jfriend00 - asked in some interview, and I am confused about the answer. Just wanna know the mechanism, why not getting `window` as answer. – Deadpool May 29 '21 at 02:44
  • "*`this` (pointing to window)*" - what makes you assume that? Please share your line of thought. – Bergi May 29 '21 at 02:47
  • Yes, but still dont get, why getting wrong answer as output! :-/ – Deadpool May 29 '21 at 02:51
  • @Deadpool It's not the wrong answer. It's the object that the `[0]` method was called on. – Bergi May 29 '21 at 02:53
  • @Bergi - How does the question you marked as a dup of explain this? More detail is appropriate here. – jfriend00 May 29 '21 at 02:57
  • 1
    Note: I you change `return arguments[0]()` to `let x = arguments[0]; let y = x(); return y;`, you do get `window`. – jfriend00 May 29 '21 at 02:59
  • @jfriend00 The dupe explains why `this` points to the `arguments` object when the function is called as `arguments[0]()`. There's nothing special here. Bracket syntax works the same as dot syntax for property access. Unless the OP shares how they arrived at `window` as the expected result, we can't write a specific answer pointing out their misunderstanding. – Bergi May 29 '21 at 02:59
  • I would add that if I was offered this in an interview, I'd immediately explain that I would never write code like this and if I encountered it in code I was working on, I would rewrite it to be far, far simpler. This is horrible code. Interviews to understand obtuse and poorly written code are fairly worthless in my opinion. – jfriend00 May 29 '21 at 03:02
  • @Bergi - Now, I know how `this` keyword works. Just marking as 'dupe' won't resolve the problem! Or, Either pls, explain how the `window` will not be the answer. This is why, I really hate SO nowadays, it is so illogical to add the dupe and Main-Title of `this` you've added. Man, anyone can find that link, but just searching for `this`. Do you think, your link will resolve this question???? – Deadpool May 29 '21 at 03:07
  • @bergi - the execution of function will return the value of this, which is `window`. What else do you want me to explain. Please, if you can't explain, kindly don't mark as dupe. I've see this trend so much in last 2 years or so.... – Deadpool May 29 '21 at 03:08
  • @Deadpool "*which is `window`*" - no it isn't. You can add a `console.log(this)` to the function or a breakpoint to confirm. You do understand that `this` is dynamically bound? And in `foo.bar()` wouldn't be `window` either? – Bergi May 29 '21 at 03:09
  • @Bergi - I updated code. Pls, see. – Deadpool May 29 '21 at 03:11
  • @Deadpool That's logging the `this` value of the IIFE, which indeed is `window` (in sloppy mode), but relevant is the `this` value in `bar`. Add a `console.log(this)` there (line 3) as well. – Bergi May 29 '21 at 03:12
  • @Bergi - I take your point, but when `this` gets inside IIFE, it never carries its context. (Parent Object - to which it should ideally point). Remember, this is not the arrow function, that carries context. So, the question is, when it gets inside IIFE, then the old-context was lost, and as `this` inside IIFE points to `window`, so it also should be. Why is it remembering old context? or why shouldn't it return `window` (from inside IIFE). That's bothering me up! Its behaving as if, it is carrying its context, like in ES6. – Deadpool May 29 '21 at 03:17
  • It's not carrying any context - it's not the `foo` object that you get. (As you say, `function`s don't carry *anything*, so there's no "old" context anyway). It gets a *new* context right in the `arguments[0]()` method call: the `arguments` object. Same as doing `arguments[0].call(arguments);` – Bergi May 29 '21 at 03:20

0 Answers0