ECMAScript bind operator proposal
github.com
github.com
I really wish we could stop building on top of this abomination (fake ES6 classes, binding, etc)
The |> operator (chaining of regular functions) would be so much better to program with. We don't need both.
I honestly thought this was common knowledge, and not that hard to grasp. How else is `this` being taught?
For whatever reason it isn't common knowledge in JS-land.
> How else is `this` being taught?
Sadly it very seldom is taught this way. It tends to be a realization people come to after using the language for a while [1].
myObj.myMethod();
Has different semantics than var x = myObj.myMethod;
x();
Which causes code like: myList.map(myObj.myMethod);
to behave somewhat unintuitively.Of course, late binding implies dynamic dispatch, but the reverse isn't true. On the other hand, almost every untyped OO language uses late binding (I can't even think of one that doesn't, off the top of my head...), as do some typed languages (those that target the .NET CLR, for example), so even with your stronger assertion JS far from unique in that regard.
That behavior is standard fare for OO. If anyone finds it tricky, I find it more likely that the struggling programmer has yet to internalize OO than that JS is doing something strange (in this particular case, I mean... JS does plenty of strange shit otherwise ;) ).
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?
b = foo.bar
b()
correctly invokes the bar method of the foo object. In JavaScript, you have to write let b = foo.bar.bind(foo)
because foo.bar gives you a function (not a method) that doesn't remember which object it came from.*My favorite is "what does `this` point to when running `eval()`"? The current context. "What if you assign `eval` to a variable and then use that?" The global context.
It all has to do with this line: "By providing syntactic sugar for these use cases we will enable a new class of "virtual method" library, which will have usability advantages over the standard adapter patterns in use today."
Essentially, you write functions that provide a certain behavior without being coupled to a specific class, so you can have a 'map' method that is called the same way no matter what you're mapping over.
Right now functional libraries like static-land, ramda, sanctuary, etc. are working hard to provide these functional primitives but it's still painful to write readable code that uses these.
It's also worth pointing out that directly importing methods here is more efficient than importing entire classes if you're not using one of those emerging build systems that does very good tree-shaking.
This is the closest JavaScript is going to get to letting you write your behavior as a suite of functions separately from specific classes—it's like a step removed from typeclasses.
There is nothing that this proposal does that cannot be done today. It brings nothing new to the table aside from operator noise. I hope the committee pushes against these exotic features, like the bind operator or the pipe operator.
> Right now functional libraries like static-land, ramda, sanctuary, etc. are working hard to provide these functional primitives but it's still painful to write readable code that uses these.
No it's not. explicit != painful .
Do people really want to end up with a spec of the size of C++ spec ?
It seems that it also extends to full expressions on the right-hand side of ::, so you can even do, for using Array operations over things that look like arrays but not quite:
document.querySelectorAll('p')::([].map)(f)
instead of: [].map.call(document.querySelectorAll('p'), f)
(replace [].map with Array.prototype.map if it feels less gross) [...document.querySelectorAll('p')].map(f)
In the future, NodeList could extend Array which would make these workarounds redundant. Extending Array was made possible by ES6.Anyhow, I think having some kind of extension methods would be great.
It would break the web, unfortunately. (We've experimented with NodeList.prototype.__proto__ being Array.prototype instead of Object.prototype and it breaks sites, and ES6's extends notion implies that.)
for(const el of document.querySelectorAll('p')) {}
Why have the overhead of a callback to begin with. It reads SO much better as well. (~R∊R∘.×R)/R←1↓ιRAnd then in template <a onClick={this.handlerFn} />
Lua is minimal. Scheme is minimal. Forth is minimal. Hell, Brainfuck is minimal. JS isn't.
You can argue that the new bind operator isn't so convenient compared to the .bind syntax, but your argument is a bit weak.
It's also worth noting that most (?) modern browsers already bind log to console. At least Chrome, Firefox, and Safari all support it. I don't have a Windows machine so I can't confirm if Edge supports it. Same goes for Node.
[1, 2, 3].forEach(console.log)And it should be in all modern browsers soon[1], as `window.console` is now a namespace: https://console.spec.whatwg.org/#console-namespace
[1]: https://developer.microsoft.com/en-us/microsoft-edge/platfor...
I would bet 3 years from now less than half of developers will be able to explain :: in an interview. Not that a much higher percentage could explain 'this' but what's done is done.
class Vector{
constructor(x = 0, y = 0, z = 0){
this.x = x;
this.y = y;
this.z = z;
setTimeout(function(){
console.log(this.x + ", " + this.y + ", " + this.z);
}.bind(this), 10);
}
};
var v = new Vector(1, 2, 3); // prints 1, 2, 3
Edit:
Ok I can see this be potentially useful for function chaining, I just don't do that very much. class Vector {
constructor(x=0, y=0, z=0) {
this.x = x;
this.y = y;
this.z = z;
setTimeout(() => console.log(this.x + ", " + this.y + ", " + this.z), 10);
}
}https://github.com/jussi-kalliokoski/trine
Is there any other language that uses "this" to denote "current context"?
The oddity with JavaScript is two-fold: firstly, the fact that it passes the global object (in non-strict code) given an z() style call (v. x.y() above); secondly, the fact that you can call a function with an explicit this argument using Array.prototype.call or Array.prototype.array.
What feels far more odd than that, though, is what the DOM does. It often acts as if there's been a method call, whereas in reality it's just called with an explicit this argument from C++. If you view a method dispatch as being a message (à la Smalltalk, a large influence on JS) then obviously an event's target is invoked as a message to the event. I obviously can't comment if that's what Brendan was thinking, but it seems like an obvious analogue.
const add1 = add::1
const createUser = post::('/user', authToken)