Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

> Is there a a reason to learn bind, where I can use arrow function, which is cleaner and more readable? (And probably does bind under the hood)

Off the top of my head, arrow functions come in handy when you're defining an "instance method" that you want to use as an event handler; you want `this` to refer to the instance, not the event. That's 95% of the time you'd use an explicit call to `bind` anyhow.

Another case to use `bind` would be a generic function that isn't specific to the type of object you're acting upon. I wrote up a short example on jsfiddle: https://jsfiddle.net/LyndsySimon/5zqtjd82/

You can also use binding to create decorators that work on instance methods: https://jsfiddle.net/LyndsySimon/n57or0u5/



sort by: page size:

> This is not correct. Arrow functions have the `this` value of the outer context.

You are correct, I wasn't clear. I was describing the end effect of free floating arrow functions VS an arrow function declared within a class.

When free floating, trying to access 'this' can (will) result in unexpected behavior, when inside a class arrow functions operate exactly as people expect a class member function to operate in other languages. (In contrast to having to otherwise bind JS functions to 'this')

In both cases the arrow function is acting the same way, but most intro to JS lessons don't explain it.

Indeed the way it was originally explained to me is that "arrow functions in classes auto bind to this" which is hilariously inaccurate, but the end effect is as if that was happening.


> How can I do this without defining a function?

You do define a function, but only once. Constructor:

  this.smth = this.smth.bind(this);
JSX:

  <button onClick={this.smth}></button>
Kind of awkward, but the standard practice last I checked. Arrow methods (terminology?) are also something you can add to the language that does the equivalent of .bind() replacements.

> The difference is that JS has no binding ... just functions that take an argument named `this`

Associating a name with a value is precisely what binding is.

Frankly, though, I don't understand this comment at all. Care to clarify for me?


> bind is a method that is present in every function

There is surely a world of unexplained knowledge in that line for someone that doesn't know JS well


> And remember, arrow functions within a class have a this, but arrow functions outside of a class don't have a this!

This is not correct. Arrow functions have the `this` value of the outer context.

I recommend this article to understand `this`: https://web.dev/javascript-this/


> How does an arrow function's implicit bind(this) poses a problem or limits generality?

Well you cant use it unbound. I dont want to declare functions bound to a scope I want a quick way to declare functions.


The syntax of the arrow function does a great job of making this explicit too. On top of that it offers 1) brevity/ease of use, and 2) standardization.

From my experience at least, binding to the outer/creating scope is something I do very often, and as far as I know my use of JS is pretty idiomatic.

Concerning 1, being able to use terser, clearer syntax for something I do so often is a huge win, and in regards to 2, it's nice to see an arrow function and to immediately know what this means, and hella better than having to search for a .bind(), var self = this, var that = this, Car.method(), etc, all equally valid as an approach, and depending entirely on the whims of the programmer behind this code.


arrow functions are not just a function() alternative, but they solve the whole 'var self = this'/'.bind(this)' boilerplate.

It's one of the best JS improvements of the last 10 years.


As has been pointed out though, that is not the primary thing that arrow functions give you. They're really there to avoid having to manually bind functions in order to maintain execution context or use the old `var self = this; function(){/.../}` workaround.

With the introduction of arrow function you won't need to use .bind(this) as arrow functions capture in their lexical scope the variables/keywords: this, arguments, super.

e.g.

setTimeout(function(){alert(this.a)}.bind(this));

becomes simply

setTimeout(() => alert(this.a));


>If you want to scope something to a block, you can just use an IIFE.

Now try doing that in a loop that you want to break out of. Edit: To save you the trouble - https://github.com/babel/babel/issues/644

>"class" is unnecessary at best. ... Why lock users into one paradigm?

It canonicalizes one of the popular ways of doing classes (the other being the same but without `new`).

>Why the hell is {bar} equivalent to {bar: bar}? Isn't that a set literal (Python, math)?

{ ... } in JS has never meant set literals. It does however mean objects (dictionary literals) which is also how Python uses it.

>You'd logically expect {[1+1]:2} to be an object with an Array (coërced to string?) key, because [] is an Array literal.

[] has also always been used to index objects and arrays, so using it when generating the object with keys and values follows as an extension of that.

>Method properties, e.g. { foo(a,b) { ... } }, are unnecessary given => functions.

Arrow functions capture lexical this, which method properties do not. Compare `({ x: 5, foo() { return this.x; } }).foo()` with `({ x: 5, foo: () => this.x }).foo()` Arrow functions also do not have an arguments object.


> Relative to the other kind of function that is written like function (x) { return x * 2 }, arrow functions don't define this or arguments in their bodies, instead capturing these values from the environment.

In the case of `this`, I can see why they did that: it is the right semantics and all of JavaScript should be this way. But I really think creating two different behaviors for what should all just be syntactic sugar around the same, ol' function values is long-term going to reveal itself as a mistake.

But that's just `this`. I can't for the life of me imagine why they also did this for `arguments`.


> The fat arrow permanently binds the value of "this"

I'm still trying to understand the details here, but my impression is that ()=>{} isn't a shorthand for function(){}.bind(this). The latter creates two functions, one with an auto-bound "this" and another with a manually-bound "this". The former creates one function, skipping the step of auto-binding a new "this" to it. So it just sees the outer "this" via the normal scope chain (I think). The idea being that JS is doing fewer things in the background and makes functional programming a little easier on the CPU.


> "This" is an ill-defined concept (illustrated by the 3 categories and 5 subcategories of the OP)

I would disagree with that.

The concept behind "this" is actually pretty simple and well-defined: it's part of the execution context that every function has in Javascript...and it's behavior is predictable based on a small set of principles outlined in the OP.

What those various examples demonstrate is that it's a dynamic concept (an important distinction imho). It's this property which gives a lot of novice developers trouble, but it's also what makes it extremely powerful.

The "effort" you speak of is the extremely minor effort of remembering how "this" behaves in a given scenario (which again, is basically one of several well-defined possibilities).....as opposed to the effort of coding "around" using "this" which will add just as much complexity to your code overall.

To me your suggestion sounds like saying you should only buy what you can pay for with exact change because it's too much "effort" to do some simple arithmetic each time to determine if you've received the correct change.

That's true of course, but this also hinders you in what you can do, and requires effort itself.

I would say both strategies have their benefits and drawbacks, but are ultimately comparable. You can certainly code "around" the this keyword; for example by using closures to create custom types instead of a constructor...

IMHO, avoiding either strategy is the wrong way to go. What you should do is evaluate each situation and determine which strategy offers the best combination of benefits and drawbacks.

In my example, using a closure might be more expressive in some ways, etc etc... but it consumes more memory, will break the instanceof operator, etc etc. There's always trade-offs.

It may be that most of your JS code doesn't require the use of "this", but if a programmer is not able to understand it and use it effectively when the situation calls for it, they will never be complete as a JS coder.


>Yep, we are using arrow functions and other ES2015+ goodies, but they don't help with event handlers.

They do. Just do:

  myHandler = (v) => {
    ...
  }
and you don't need to bind in the constructor anymore. You'll need to use Babel of course to transpile that.

How does an arrow function's implicit bind(this) poses a problem or limits generality? (Honest question; I'm not a JS wizard.)

You shouldn't use bind() for two very good reasons. First, it's performance is abysmal. Second, if you .bind(foo) a function and .call(bar) on it later, it silently ignores the new 'this' argument.

I think the new arrow functions are neat, but am I the only one who never really found it a hassle to throw a .bind(this) on a function?

Maybe the problem is that you're asking questions built around bad ways of writing code, that good developers simply avoid. bind() doesn't even work on IE 6, and nobody in their right mind would pass a callback function around that uses "this" and later check that "this" refers to the same object.
next

Legal | privacy