1. You can implicitly return things so it provides nice syntactic sugar
2. Using an arrow function results in `this` being bound in the way you'd expect (coming from something like C++) in all cases without having to call .bind(this) anywhere. I'll never forget seeing promise chains starting with `const that = this;` in order to keep the right reference throughout the promises.
3. You use it for the previous 2 reasons and use it everywhere in order to be consistent
With three, I disagree. It is kind of like saying let us just use var everywhere to be consistent.
For example, an arrow function accessing variables outside its scope is much slower, something you will notice when processing a lot of data in nodejs.
And if you're working in the browser and trans-pilling down to ES5, babel needs to do a lot more work.
But as long as people are aware of the trade-offs, they can use whatever works for them.
That doesn’t sound true. Do you have any evidence? (Under an uncommon JavaScript engine?)
Probably a side-effect of what I usually choose to comment on, which are things that are objectively wrong or seriously misleading :) I think the HN voting system is poor, so I don’t use it, myself.
> Remember, an arrow function shares the same scope with [its] parent function
Exactly like a non-arrow function, then?
> Do you have any evidence to the contrary? I have experienced it when processing heaps of textual data in nodejs (the same engine that runs chrome). My script was crashing for no apparent reason, and just changing the arrow functions solved it.
Not only is that not evidence, it doesn’t support what you originally said. Slower ≠ crashing for no apparent reason.
If you mention which version of Node this was, I can go looking for evidence.
Do you have any evidence that you do not use it?
> Remember, an arrow function shares the same scope with [its] parent function >> Exactly like a non-arrow function, then?
No, not exactly. It looks like I need to be more explicit, here goes: Remember, an arrow function's BODY shares the same scope with its parent function
> Do you have any evidence to the contrary? I have experienced it when processing heaps of textual data in nodejs (the same engine that runs chrome). My script was crashing for no apparent reason, and just changing the arrow functions solved it. >> Not only is that not evidence, it doesn’t support what you originally said.
It is called ANECDOTAL evidence, and yes, it is a thing. If you want SCIENTIFIC evidence, sorry I just do not have the time and energy. If you want to believe that arrow functions are a drop-in replacement for normal functions and that they are always better and faster in all situations, go ahead and believe that. And you'll do just fine, as long as all you are doing with JS is React and basic UI wrangling stuff.
> Slower ≠ crashing for no apparent reason.
My friend, this is a discussion, not a scientific thesis or a legal document. I do not have to explicitly explain every little detail and cover every little phrase so that someone does not misqoute me. Be generous enough to try and understand something someone is saying. So, to rephrase that too, when I say "crashing for no apparent reason" I mean "crashing for no apparent reason that I could find by looking at the code over and over again searching for bugs or typos". And yes, it was crashing due to timeout and memory issues. Please dont start arguing about how crashing and timing out are not technically the same thing.
Exactly like a non-arrow function, then?
I don’t mind if you don’t have the energy to support your claim, but I will recommend that you don’t make claims like “arrow functions are slower” if you can’t back them up properly or even provide any detail.
I also get the impression that you don’t know how arrow functions actually differ from non-arrow functions (see above), so your anecdote that you couldn’t figure out the bug doesn’t make a strong case.
> Do you have any evidence that you do not use it?
My browser was crashing for no apparent reason and stopping voting on HN solved it.
It is both method and closure. Which is not universal - io has method and block, ruby has def and block
And it is constructor. So it can be called both with and without `new` with different results. Other can't:
arrow = () => {}
// new arrow()
// TypeError: arrow is not a constructor
object = {
shorthand() {},
['computed']() {},
get getter() {}
}
// new object.shorthand()
// TypeError: object.shorthand is not a constructor
// new object.computed
// TypeError: object.computed is not a constructor
// getter = Object.getOwnPropertyDescriptor(object, 'getter').get
// new getter
// TypeError: getter is not a constructor
class Class {
static staticMethod () {}
method () {}
get getter() {}
}
// Class()
// TypeError: Class constructor Class cannot be invoked without 'new'
// new Class.staticMethod
// TypeError: Class.staticMethod is not a constructor
// klass = new Class
// new klass.method
// TypeError: klass.method is not a constructor
// getter = Object.getOwnPropertyDescriptor(Class.prototype, 'getter').get
// new getter
// TypeError: getter is not a constructor
function* generator() {}
// TypeError: generator is not a constructor
// new generator()
I actually was surprised just how many ways TC39 introduced so we do not use function. The change you observe is not a coincidence - it is carefully crafted."function" is too entrenched. It's usage as a constructor appeared even before .prototype:
function Cat() {
this.say = function() { return 'nyan' }
}
All the confusion about javascript object system is because of classes which have no name, we call them by their constructors. Give them real names: Cat = class {}.prototype // or function {}.prototype
Cat.say = () => 'nyan'
cat = new Cat.constructor
cat.say()
cat.__proto__ === Cat
A little bit inconvenient... oh! it's everywhere: cat instanceof Cat.constructor
Tom = class extends Cat.constructor {}.prototype
And all the base classes are constructors Object = Object.prototype
with their helper methods, it should be separate like Reflect and Math: Reflect.create = Object.constructor.create
object = Reflect.create(Object)
There is no simple answer, breaking change is not an option, let the planned obsolescence begin.And it works! Slow but steady so much done since 2012 http://brendaneich.github.com/Strange-Loop-2012/#/
I'm not convinced at all, we'll simply have to agree to disagree on that.
And I'd love to see the codebase of a JS app that completely bans the "function" keyword. Any links or examples?
>> Yes, <typo>they</typo> replace<typo>d</typo> "function" usage with safe alternatives. And don't forget 'use strict' - it affected "function" too.
> I'm not convinced at all
It could appear I've tried to convince you not to use "function". That never was the case, should have added at least one. And I do not agree with TC39 direction, just making observations. Please check my comment assuming that and typo.
My fix would be different. Prototype based inheritance is awesome http://iolanguage.com/tutorial.html and javascript could be as simple too:
Object
Object.__proto__ === null
object = new Object
object.__proto__ === Object
object.constructor === Object.constructor
object.toString === Object.toString
f = new Function
f.__proto__ === Function
fun.constructor === Function
object.private = function () { return 'hello' }
Object.shared = function () { return 'world' }
Object.constructor.static = function () { return '!' } // we need functions
with just a simple change Object = Object.prototype
Function = Function.prototype
syntax new = function (ctx) {
let ident = ctx.next().value
return #`new ${ident}.constructor`
}
It looks almost boring (just don't redefine .constructor). Now this one is much harder: Object.prototype
Object.prototype.__proto__ === null
object = new Object
object.__proto__ === Object.prototype
object.constructor === Object
object.toString === Object.prototype.toString
fun = new Function
fun.__proto__ === Function.prototype
fun.constructor === Function
object.private = function () { return 'hello' }
Object.prototype.shared = function () { return 'world' }
Object.static = function () { return '!' } // we need functionsBtw, it's not banned, and I never really enforced it... but since I never use it myself, I guess the others devs picked it up?
It's in Vue.js, and in Vue you rarely see old-style functions anywhere, so there's that.
source: https://raw.githubusercontent.com/vuejs/vue/dev/dist/vue.com...
Furthermore, the official Vue documentation explicitly discourage the use of arrow functions in some places, so whoever set that rule just did not know what they were doing, sorry if that sounds harsh.
source:
- https://vuejs.org/v2/guide/instance.html#Instance-Lifecycle-...
- https://stackoverflow.com/questions/43929650/vuejs-why-is-th...
Saying all arrows functions are bad and evil or that all normal functions are bad and evil is nothing but dogma. Each has its own place and uses, it seems many JS devs would rather not think of this at all and just use one form everywhere.
We're using shorthand syntax in methods inside Vue.js objects [1], they also don't need the "function" keyword. In fact, they are suggested in the second link you posted, please read again. Arrow functions wouldn't even work in this situation.
We're mainly using two forms: shorthand and arrow. That's how we only have 21 instances of the "function" word in our entire JS codebase, and we could remove all of them if we wanted. That's what you asked for: a "JS app that completely bans the 'function' keyword". Well, we don't ban but it's possible.
And please read my comment again: I explicitly mentioned that this is not a rule, and I never enforced it. The team (39 committers ATM) reached that result organically, mostly influenced by my own personal style.
And sorry if this sounds harsh, but it seems that you have extremely limited knowledge of Javascript and ES6, so I'd suggest learning before you make such claims before you make a fool of yourself.
Btw, you're seem to be the one holding on to dogma here, since you seem unable to accept that the keyword is not strictly necessary in a large app.
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
And there was no goal intended with the grep. This is what you wrote:
> And I'd love to see the codebase of a JS app that completely bans the "function" keyword
I just grepped "function" to give you a personal anecdote of an app that doesn't need to use the "function" keyword much.
That was the first time I interacted with you, I was trying to be nice then, and you were completely hostile. Some of the replies were completely uncalled for.
---
EDIT: You just edited your message to add the part about shorthand methods. My point still stands. I never claimed to be only using arrow functions (in fact, you're the one who DID claim I was only using arrow functions!). I only claimed we rarely use the "function" keyword.
1) Hoisting + mutability
a = 'lol';
function a() {}
a() // error
2) one-liners const findByName = (list, name) => list.find(item => item.name === name);
//vs
function findByName(list, name) {
return list.find(item => item.name === name);
}
3) signaling that `this` keyword usage should not happenTo ask the same question differently, what about functions that do not need 'this'?
It's easier to use arrow functions for everything except for the tiny minority of cases where you want prototype this.
function doThing( event ){}
Why does everyone seem to be using the first format? Isn't the second version a lot more readable/pretty? Even worse is when doThing is immediately exported and not refferenced anywhere else, but still there is this need to assign it to a const.