rse / es6-features

ECMAScript 6: Feature Overview & Comparison

Home Page: https://rse.github.io/es6-features/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lambda example improvement

fhalde opened this issue · comments

In the lexical this the ES6 and ES5 (1st variant) examples doesn't really show any difference.
The this in lambda depends on the context where the lambda was created. Here both are assumed to be global. Had the ES6 example kept such that the lambda was created inside another function/context where the this object is something other than the global this, then it would make more sense!

function test() {
  this.nums = [1, 2, 3];
  this.fives = [];
  this.nums.forEach((v) => {
       if (v % 5 === 0)
           this.fives.push(v)
   })
}

new test();

Why do you think the examples assume a global context? "this" references the context, independent whether it is the global context or a local context of a function. If the code snippets are run in global contect then "this" is actually "global" (Node.js) or "window" (Browser), yes. But if the same code snippets are run in a local context then this is actually the context of the surrounding function. For the illustration of lexical "this", does it matter in your opinion? The point is not that "this" is a context pointer, but that one does not need helper variables like "self" to be able to use it inside a callback function.

ok the es5 variant 1 would've worked without introducing the self variable too! That confused me.

And I thought well

Removing the self variable and just using the this straightaway is fine too. What is the point this example is trying to convey?

No, in the following variante 1 it would not work without "self":

5| //  variant 1
5| var |self| = |this|;
5| |this|.nums.forEach(|function (v)| {
5|     if (v % 5 === 0)
5|         |self|.fives.push(v);
5| });

Because without "self" an inner "this.fives.push(v)" would reference the context of the "function (v)" and not the one which is referenced by "this.nums...".

Boy this was a bummer. Thanks! @rse

Now I dont understand the following

/* global context */

this.fives = [];
function(v) {
 this.fives.push(v);
}

this refers to global

but

/* global context */
this.fives = []
[1,2,3].forEach(function(v) {
  this.fives.push(v);
});

this refers to ???

No, even in your first code snippet the "this.fives" does NOT reference the "this.fives" outside the function. The point is that "this" inside a "function" (in contrast to an ES6 arrow function!!) points to a local context of the function. So, in your first code snippet "this" ouside the function references the global scope, but "this" inside the function references the local scope of the function.

In your second code snippet this is not different. It makes no difference for the function whether it is a plain function (as in the first snippet) or a callback. It will always have its own local context, except the function is called as a method on an object. But .foreach() does not do this. It just calls the function and hence the function still has its local scope.

hmmm i remember doing the following exercise in node

file a.js

var self = this;
console.log(this);
function hello() {
  console.log(this);
  console.log(this == self); // false !!!!!
}

both printed the same global object but the equality was wrong

Yes, of course! Once again: "this" inside the function is a different scope than "this" outside the function. So, obviously "this === self" is "false", of course. That's why one used the "self" variable in ES5. And that's the point of ES6 arrow functions: Their "this" is the same as the "this" outside of it, so no more "self" is needed.