0

EDIT: I think this isn't a duplicate; it being a hidden parameter, I wanted to ask about shadowing in relation to this, and lexical scoping, having read this SO Q/A re. shadowing.

I had thought that the meaning of the name this might be resolved kind of dynamically (in terms of scoping), so as to explain why it doesn't seem to me to be resolved lexically:

function foo() {return this;}
var a = {f: foo};
var b = {f: foo};

a.f() !== b.f();
a.f() !== foo();
a.f() !== window; //not strict mode

But then I read that every function receives this as an additional parameter, silently. (I realise arrow functions are different.)

Obviously helper() doesn't work as we might hope:

ob = {
  meth: function(){
    var helper = function() {return this;};
    return helper();
  }
};
ob.meth(); //Window or undefined

As far as I understand, rather than this being resolved by looking at the enclosing scope (the result being ob), instead the interpreter is calling helper() with this set to undefined (strict mode), silently passed as an argument.

So is the surrounding scope's this effectively being shadowed, hence lexical scoping is in fact in action?

Community
  • 1
  • 1
KnewB
  • 353
  • 4
  • 16

2 Answers2

0

You are correct. Except in the case of arrow functions, this is never resolved lexically. It always refers to one of the following:

  1. the object upon which a function was called, such as valueOfThis.foo()
  2. the first argument to apply or call, such as foo.apply(valueOfThis, params) or foo.call(valueOfThis, ...).
  3. the DOM element, in the case of event handlers, such as <button onclick="alert(this.tagName.toLowerCase());"/>
  4. the object being constructed, when a function is used as a constructor, such as Foo = function(){ ... }; new Foo()
  5. the object bound to the function, if the function was created using bind, such as bar = function(){ ... this ...}; foo = bar.bind(valueOfThis); foo()
  6. in a getter/setter, this refers to the object for which the property is being accessed or set, such as valueOfThis.someProperty = 123
  7. window (usually) if none of the above cases, such as foo()

@Bergi provided a great reference for all these in the comments below.

In the case of bound functions, the function being called is actually a different function than was passed to the bind method, because the bind method creates a new function

GreenGiant
  • 4,226
  • 1
  • 40
  • 69
  • …or to something else. Your list is not exhaustive. – Bergi Mar 10 '16 at 21:08
  • what is _this_: `[1,2,3,4,5].filter(/./.test, /[02468]$/)` here ? `div.onclick()` too. `setTimeout(that.method,0);` too – dandavis Mar 10 '16 at 21:09
  • @Bergi could you tell me what I'm forgetting? – GreenGiant Mar 10 '16 at 21:10
  • 1
    @dandavis I don't see a reference to `this` in your code. If you're asking what `this` refers to inside the `filter` function, then it will refer to the array – GreenGiant Mar 10 '16 at 21:11
  • 1
    @GreenGiant: just because you don't see `this` doesn't mean it's not used by a method... ` In the case shown, `this` refers to the RegExp, not the Array, since `[].filter` uses its 2nd argument as `this` on the callback. – dandavis Mar 10 '16 at 21:12
  • @GreenGiant: `new`, bound functions, and probably [more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this). – Bergi Mar 10 '16 at 21:12
  • @dandavis ok it wasn't clear which function you were talking about. Yes, you're right, `this` refers to the second regex when `test` is called as a callback by `filter`. But that is just a special case of #2 above. `filter` is internally calling the callback via something like `callback.apply(thisValue, ...)` – GreenGiant Mar 10 '16 at 21:24
-1

So is the surrounding scope's this effectively being shadowed, hence lexical scoping is in fact in action?

Yes, one could view it from that perspective. The this bound to the helper scope shadows the one bound to the meth scope. (And if you had used an arrow function, it wouldn't).

However, you still need to remember that this is not an ordinary variable but a special keyword. It is only bound to function scopes, it's not writable, it has weird coerce-to-object semantics in sloppy mode, and it's always implicitly bound - as you say, a hidden parameter.

Unless you're trying to understand how this works in arrow functions (and their lexical resolution), the analogy with scopes and shadowing is pretty useless.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164