`this` binding operator

I wonder that why no one talks about this proposal (or did I miss it?).

There're no updates on it since 4 years ago either.

What is the stage of this proposal, and, is there any progress on it?

Proposal: GitHub - tc39/proposal-bind-operator: This-Binding Syntax for ECMAScript

This has evolved into Extensions and :: operator (stage 1). But there's also a Bind operator for JavaScript which may ultimately swoop in and replace it, though I'm rather fond of the original (your link) myself.

1 Like

This made me think; Is there any proposal which allow immutable bindings??
like:

function foo() {
    console.log(this)
}

const obj = { }


let ifoo = foo.ibind(obj)
ifoo() // obj

foo() // globalThis

like something that roughly emulates call and bind?

I'm not sure I understand what you mean by "immutable binding" - how would it behave any differently from how function.bind() already behaves?

Essentially all the use cases for it have been subsumed by two things:

I don't see it getting anywhere, and I'm almost surprised the repo hasn't been archived already.

what I meant is that something that doesn't affect the context of the bound function instead returns a copy of the function with the given object as it's context.

That's what .bind() already does.

> function f() { return this }
> f.bind({})
> f() // f remains uneffected
<global object>

I meant this☝

I'm sorry - I'm still lost. If I replaced ibind with bind in your example code snippet, then it will still output "obj" and "globalThis" at the end, depending on which function you call. Could you perhaps show an example that contrasts ibind() with bind() and shows how they're different?

1 Like

sorry my bad I just got lost; you're right!:+1:

Just because a feature exists doesn't mean you have to use it. For one, I rarely use classes outside frameworks that require it (like React), and I also don't commonly use Object.create.

And to be quite honest, even ?. only aids readability in cases where you deal with a lot of optional data, so I don't even use it a ton.

Can you give some examples about how pipelines replace the :: operator? I don’t see any overlap between them.

From the bind operator repo:

import { map, takeWhile, forEach } from "iterlib";

getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));

Direct equivalent using pipeline operator (in current form):

import { map, takeWhile, forEach } from "iterlib";

getPlayers()
|> map(^, x => x.character())
|> takeWhile(^, x => x.strength > 100)
|> forEach(^, x => console.log(x));

And for the other half of the bind operator (method bind taken from proposal):

// Function bind
function doReset(v) {
  return this.reset(v, whatever)
}

Promise.resolve(123).then(value::doReset);

// Method bind
Promise.resolve(123).then(::console.log);

Direct equivalent using partial application (in current form), modulo rest parameter support:

// Function bind
function doReset(value, v) {
  return value.reset(v, whatever)
}

Promise.resolve(123).then(doReset(value, ?));

// Method bind
Promise.resolve(123).then(console.log(?));

Those aren't replacements, because in the bind version, map looks at its receiver; in the pipeline versions, it looks at its first argument.

The pipeline equivalent would be map.call(^, x => x.character()) etc. There is no equivalent to the bind operator because there is no other syntactic way to specify the receiver of a function.

1 Like

I meant functionally, not literally. For most purposes (like excluding installed getters, etc.), the two ways are mathematically isomorphic, and that's what I'm looking at.

Oh, is it being bound to the first parameter of a function? I don’t think this is a good idea. In fact, I am assuming that it is only bound to the this keyword, i.e. console::log equivalent to console.log.bind(console).

The difference I described is the critical one, and the motivation for the bind operator - I'm not sure why mathematical comparisons are relevant, and I think it's very misleading to imply that the two proposals aren't both useful/needed for different reasons.

A lot of people were wanting the original bind proposals because it provided a nice way to use custom method in the middle of a fluent API chain. The pipeline proposal also fulfills this need completely. For many people, the pipeline proposal will lose a lot of value, because the primary use case got superseded by another proposal.

The current iteration of js-choi's bind proposal specifically states that the above use case is not a goal of the new bind operator proposal - this is specifically the job of the pipeline operator. Instead, it seems the goal was originally to provide a syntax to protect against global prototypal mutations, but In issue #8 it was mentioned that to proceed, they needed to change the focus of the proposal to general ergonomics of using the bind syntax over the bind method, along with what benifits the community would have if we made it easier to do this-binding. I'm not yet sure how strong of an argument can be made around this new objective, we'll see (I still need to have a closer read over the updated README that presents it), but it certainly seems to be a very different objective than what many people were rooting for in the original bind proposal.

For what it’s worth, @theScottyJam, @ljharb, and I collaborated on a statistical corpus study over the year-2019 top-1000 NPM packages. The results are summarized in the bind-this explainer’s rationale section—even excluding transpiled code, .call and .bind occur very frequently, comparably to console.log, .slice, and .push. .call and .bind may therefore be two of the most commonly called functions across all JavaScript code. So we argue that this frequency alone (plus the clunkiness of .call/.bind’s flipped word order) was sufficient to consider new syntax.

In the October 27 plenary, bind-this was presented to the Committee with these arguments, and it successfully achieved Stage 1. I plan to continue working on progressing the proposal through the Committee, and I plan to continue to work with the champion of the extensions proposal to reconcile the two rival proposals.

2 Likes