4

Say I have a lambda in TypeScript:

 myArray.forEach(o => o.x = this.x);

The value of this becomes window instead of the calling object. What I'd really like to do is:

 myArray.forEach(o => { o.x = this.x; }.bind(this));

But I don't see that as an option in TypeScript. How can I override this in a TypeScript lambda body?

Delimitry
  • 2,987
  • 4
  • 30
  • 39
Josh M.
  • 26,437
  • 24
  • 119
  • 200
  • 3
    Of course, you could always use `myArray.forEach(o => o.x = this, this.x)` :-) – Bergi Dec 08 '14 at 18:16
  • Well that's actually the answer - make it official and I'll accept it. :) I didn't think to check for other parameters to `forEach`. – Josh M. Dec 08 '14 at 18:22
  • Yeah, but you asked about typescript lambdas in general; the additional parameter won't help you everywhere. – Bergi Dec 08 '14 at 18:24
  • Yes it does .... `myArray.forEach(o => o.x = this.x, this)` ... is the solution. – Josh M. Dec 08 '14 at 18:25
  • 1
    @JoshM Can you give more code to reproduce your issue? I'm not understanding it... http://goo.gl/c2lqYZ – David Sherret Dec 08 '14 at 20:42
  • Inside the lambda, `this` defaults to `window` instead of the owner of the calling function. So, passing `this` as the second parameter to `Array.forEach` "fixes" this issue and the lambda's `this` reference will be the same as the calling function's `this`. – Josh M. May 26 '15 at 03:26

1 Answers1

2

Just FYI even without a lambda the default this in a for each is window e.g. :

[1].forEach( function ( o ) { console.log( this ) }); // window

To fix the this with bind you need to use a function and not a lambda (which lexically scopes the meaning of this).

var foo = {};
[1].forEach( function ( o ) { console.log( this ) }.bind( foo ) ); // object `foo`

Alternatively you can use the second argument for forEach as mentioned by Bergi.

basarat
  • 261,912
  • 58
  • 460
  • 511
  • Actually, *with* a lambda (or correctly: arrow function) the `this` is *not* `window`. – Bergi Dec 09 '14 at 00:13
  • 1
    If you want to be pedantic then : not _necessarily_ `window` unless the immediate upper scope is global && you are in a browser environment. – basarat Dec 09 '14 at 00:38
  • Your first two recommendations are not necessary. Your last recommendation is the correct answer: `myArray.forEach(o => o.x = this.x, this);` – Josh M. Dec 09 '14 at 13:39