Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I was almost afraid no one else thought this way. This just makes JavaScript illegible, and adds a negligible number of new features. The only JS I'm ever going to write is ES5, at this point, because the difference between

  function Person(){
    this.age = 0;
    setInterval(() => {
        this.age++;
    }, 1000);
  }
and

  function Person(){
    this.age = 0;
    var my = this;
    setInterval(function(){
        my.age++;
    }, 1000);
  }
are barely visible, but the second one is actually legible. Why are we arrowing in nothing into curly braces? Oh, it's actually a function. Great.


A better example, in my opinion:

    let names = persons.map(p => p.name);
Compared to ES5:

    var names = persons.map(function(p) { return p.name; });
The arrow syntaxes increases readability pretty much everywhere. Promises, for example:

    save(value)
      .then(result => this.update(result))
      .catch(err => Application.showError(err, "Could not save."))
(The use of a function in the "then" here is to avoid having to bind() the function; the alternative would be: .then(this.update.bind(this)).)

Your setInterval example is a somewhat inappropriate example of the usefulness of arrows as it doesn't take any arguments and doesn't return anything (so you didn't need the braces).

But the fact that you have to alias "this" is a big argument in favour of arrow syntax. It may be trivial in a small example, but it's not trivial when extended to an entire app. You'll pretty much end up aliasing "this" in every single method. If you change any logic around, you'll end up having to either add new aliasing, or chase down unused alias variables, just to add/remove closures. (And what do you call that variable? Is it "this_" or "_this" or "self"? When working on a team you'll have to agree on a convention if the code is to remain readable.)


MDN thought it was a good example... [1]

And your second example; I was going to re-write it, but then I realized I couldn't because I didn't know what `this` was. I don't think `this` is useful, and I try to avoid it because of its malleability and the confusion it often brings because of its overly dynamic nature.

[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... , Ctrl-F for `Person` or something


That MDN page gives a good example of how it works, but it's not intended to convince doubters with persuasive arguments.

Not sure why you don't know what "this" is in the second example. The whole point is that it's predictable. "this" is always the instance your method is defined in, unless you bind it to something else, which requires being explicit. I intentionally didn't include any context, but think about it this way:

  class Store {
    save(object) {
      this.client.put("/objects", JSON.stringify(object))
        .then(result => this.update(result))
        .catch(err => Application.showError(err, "Could not save."))  }
    }
  }
"this" is extremely useful. I'm not sure how you could argue otherwise. Here's another pattern I use all the time:

  this._socket = new WebSocket(`ws://${url}`);
  this._socket.onopen = () => {
    this._state = 'connected';
    this.emit('connected');
  };
The lambda syntax allows placing logic lexically where it belongs.


I haven't touched JavaScript in years, so I'm curious about one detail: why does the second snippet need you to alias "this" to "my" and the first doesn't? If it wasn't for that, it would look like mere syntactic sugar for lambdas, but this difference makes me think there's something more to it.


Function calls bind "this" to the caller. So if you do:

  foo.bar()
then inside bar(), "this" is foo. Whereas if you do:

  quux(function() { console.log(this); })
...the "this" will point to whatever quux's "this" is, and it could be anything, depending on what quux() is doing. You can't depend on "this" being correct here.

Hence people have for years used bind():

  quux(function() { console.log(this); }.bind(this));
But this is neither nice to read (or write), nor is it performant. Many libraries, such as Underscore, also allow you to pass in a context variable:

  quux(function() { console.log(this); }, this);
This requires that quux() passes the context as the "this" argument to the function.

The lambda (arrow) syntax fixes all of this [pun] by preserving "this" as a lexically scoped reference:

  quux(() => console.log(this));


It is a feature of the new syntax to bind the current context (what "this" points to) to the created function.

http://tc39wiki.calculist.org/es6/arrow-functions/


It actually is required, because `this` is mangled whenever you create a function. If I added .bind(this) to the function, it would also work, but I alias the object instead. Yes, it's confusing, but the fact that there's a difference is even more confusing.


"this" inside the setInterval in the 2nd example points to the global object in the browser case it's the window. So, he had to cache/alias the value prior to execution to avoid the confusion.


I agree that the second example, using (var my = this) and then using my inside the anonymous function is not much of a hassle.

However, in my opinion, repeating this many many times throughout a codebase is irritating to write, and adds extra weight and bug surface area to the code.

Therefore adding some syntax sugar to remove the need to do this, i.e. the first example, is a nice feature. I know opinions on syntax and formatting are pointless and endless, but could you please explain why, for you, is it less legible? Once you're used to it, don't you just scan () => as no-arg anon function signature the same way you scan function() as that now?


I agree, but closures and bine are expensive--present in both cases. It's better to avoid it. Granted, this is a contrived example and sometimes closures are the more elegant solution.

  function Person() {
  	this.age = 0;
  	setInterval(this.incAge, 1000, this);
  }
  Person.prototype.incAge = function personIncAge(that) {
  	that.age += 1;
  };
http://jsperf.com/bind-vs-closure-vs-param


Ugh — this plague again. No other coding community has latched on to performance tests like the javascript one. For NO GOOD REASON.

They're not expensive. You're not binding thousands of times a second anyway, so stop your silly premature optimizations.


1. I already gave an out for your point. Yes, always weigh performance vs. clarity and don't over optimize.

2. You are making an assumption that you aren't binding thousands of times a second. You need to take actual use case into consideration.

3. My example has a 1000:1 method call to bind ratio and it's still a significant difference in benchmarks. Yes, it's that expensive it's important to think about in critical sections of code.


Meh; rockstar developers with no CS background working for over valuated MVP companies implementing half understood techniques described in shady Haskell tutorials cannot possibly be wrong.


Well, the no CS background and shady Haskell tutorials parts were correct; My highest formal education is high school. ;) But this was done on my free time, and I don't really identify myself as a rockstar developer. Sounds pretty arrogant to me.


Do you know that the arrow function was the main reason that I made the switch from Chrome to FF Dev as my primary web browser and I never looked back?

You don't know how much you're missing here. I wish that ECMAScript* considers adding support for "indented syntax" like in Sass to make it even more easier to read and go through the codebase without seeing all these ugly braces around.

*: or a white knight programmer volunteering to offer this functionality for us all :)


That's CoffeeScript right there for you.


I'm familiar with CoffeeScript but AFAIK it's a distinct language probably a dialect of JS.

I just want the indentation without all the baggage that comes along with CoffeeScript.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: