tc39 / proposal-call-this

A proposal for a simple call-this operator in JavaScript.
https://tc39.es/proposal-call-this/
MIT License
121 stars 5 forks source link

Real-world examples from Node.js #5

Closed js-choi closed 3 years ago

js-choi commented 3 years ago

I am seeking real-world examples of code that would be improved by a syntactic this-bind operator.

According to @ljharb and @bmeck, Node contains many methods that bind various intrinsic global methods in order to avoid being affected by external prototype pollution. @bmeck gives this example in tc39/proposal-extensions#11:

// instead of
const slice = Function.prototype.call.bind(Array.prototype.slice);

function copyArray(arr) {
  return slice(arr);
}

// The adversary’s external code.
delete Array.prototype.slice;
delete Function.prototype.call;

// Our own trusted code, running later.
// In spite of the adversary’s code, this does not throw an error.
copyArray(arr);

…which in this proposal would be improved to:

// Our own trusted code, running before any adversary.
const { slice } = Array.prototype;

function copyArray(arr) {
  return arr->slice();
}

// The adversary’s external code.
delete Array.prototype.slice;
delete Function.prototype.call;

// Our own trusted code, running later.
// In spite of the external code, this does not throw an error.
copyArray(arr);

Where in Node.js (or elsewhere) does this pattern actually occur? We need to transplant examples from them into the explainer.

ljharb commented 3 years ago

Any part of node that uses the "primordials" pattern pulls in, for example, ArrayPrototypeSlice.

With this proposal, it could name that slice, and then do arr->slice(x, y) instead of what it does now: ArrayPrototypeSlice(arr, x, y).

bmeck commented 3 years ago

I'd note that primordials in node do sometimes do much more than just uncurry the this value so it wouldn't remove the need for primordials entirely, just most of the prototype methods.

js-choi commented 3 years ago

For future reference: nodejs/node#30697 and lib/internal/per_context/primordials.js.