Ecma262: Arrow functions do not .bind()

Created on 7 Dec 2017  路  6Comments  路  Source: tc39/ecma262

Hello,

A coworker of mine unfamiliar with Javascript (he's a Scala dude) pointed out to me that this code right here

const lambda = (() => this.foo).bind({ foo: 1 }) // returns undefined
const properFunction = (function() { return this.foo }).bind({ foo: 1 }) // returns 1

works a little quirky: though we're explicitly binding a context to the lambda, not only does it fail, which is understandable given their lexical this contexts, but it gives _no feedback to the developer_.

Not sure if this is a browser issue or a language issue, but I thought I'd start a conversation about this. Please let me know if this is better suited to the web platform as opposed to TC39 and I'll gladly close this and open it elsewhere.

Thank you for reading! 鉂わ笍

question

Most helpful comment

@TejasQ a similar "issue" exists with function foo() { }.bind(this).bind(this) - if it doesn't fail the second time, then (() => {}).bind(this) shouldn't fail.

Similarly, var self = this; function foo() { self.something(); }.bind(this) doesn't have the effect you intend, but that couldn't be made to fail - in other words, using .bind has always required you to have intimate knowledge about the implementation of the function to guarantee an effect, including whether it's already bound, or if it's an arrow function, or it it even references this at all.

All 6 comments

Yeah thats a feature of es2015. They don't want us to bind contexts around. Use arguments

@TejasQ a similar "issue" exists with function foo() { }.bind(this).bind(this) - if it doesn't fail the second time, then (() => {}).bind(this) shouldn't fail.

Similarly, var self = this; function foo() { self.something(); }.bind(this) doesn't have the effect you intend, but that couldn't be made to fail - in other words, using .bind has always required you to have intimate knowledge about the implementation of the function to guarantee an effect, including whether it's already bound, or if it's an arrow function, or it it even references this at all.

I guess (disclaimer: I don鈥檛 know Scala) that the core issue is that _it is not possible to bind a new this-value to a function whose this-value is already bound_. Instead, Function#bind will just silently _ignore_ the provided value.

In the particular case, the this-value of the arrow function is already bound to the this-value of its enclosing scope.

There is some logic behind that behaviour, but you need good understanding of the JS function model in order to grasp it, and it may be unexpected for people accustomed to other models.

Forbidding .bind at all is also a bad idea because you can still use .bind for partial application.

const add3 = (a, b, c) => a + b + c
const add2 = add3.bind(undefined, 0)
const plus5 = add2.bind(undefined, 5)
plus5(3) // 8

This seems answered; @TejasQ, is it ok to close?

Indeed. Though I'd reiterate as a closing thought that a greater deal of verbosity here could help. Thank you all for your consideration!

Was this page helpful?
0 / 5 - 0 ratings