Comments (4)
@acutmore left a comment on the Gist, to which I’m replying here:
// The adversary’s code.
delete Set.prototype.slice;I think this was supposed to be
delete Set.prototype.has
:)
Yes, the delete Set.prototype.slice
is a mistake; thanks for catching it!
There is currently no way to harden trusted code against an adversary’s mutation of Function.prototype.call or Function.prototype.bind.
This is not entirely true. It can be hardened against it just relies on being able to run code before anyone else (just like capturing any global/method before it can be modified).
// at start before other code runs: const uncurryThis = Function.bind.bind(Function.call); // f => Function.call.bind(f) // f => (…args) => f.call(…args) // or const {apply} = Reflect; const uncurryThis = f => (that, …args) => apply(f, that, args); // then const setHas = uncurryThis(Set.prototype.has); // later setHas(new Set([1]), 1); // true
It is true that guarding against Function.prototype.call
mutation is possible with Function.bind.bind
. This is another old mistake which I’ll need to fix.
This guard requires wrapping every global method you use in an uncurried-this
wrapper function, à la @ljharb’s call-bind library, which is transitively used by a ton of websites.
So the argument that I need to make is that (1) this intrinsic call-binding is just one common use case of a very commonly used pair of functions (bind/call), and (2) despite its frequency, using bind/call is currently clunky and its ergonomics should be optimized with an operator.
I do anticipate that the biggest argument against this will be “the method-wrapping is fine; just use the pipe operator |>
if you want a fluent postfix expression”. I am still trying to think of ways to respond to that reasonable objection. But first I need to modify and import this Gist.
from proposal-call-this.
to me it’s really not about the postfix part, i just need a way to syntactically change the receiver of a function - it’s just that once that exists, it’s kind of silly to force the awkward ordering of .call when we could easily have natural o.a(b)
ordering.
from proposal-call-this.
i just need a way to syntactically change the receiver of a function
@ljharb: People will probably say, “Why do you need syntax to change your function’s receiver? Why not just keep using Function.call
or your uncurryThis
/callBind
wrapper?” It’s already kind of happened in that Matrix conversation, too.
The best argument against that anti-argument that I can think of is developer ergonomics. Using Function.call
/uncurryThis
/callBind
is weird, clunky, and obscuring. o->fn(a)
or whatever is more ergonomic than Function.call(fn, o)
because it’s less wordy and because the ordering resembles o.fn(a)
.
If it weren’t for that ergonomic difference, then it’s like what @acutmore said: everything is already possible in userland without syntax. (Possible inherent performance problems with wrapped functions notwithstanding, cf. #8.)
from proposal-call-this.
Part of it is robustness, and part of it is ergonomics. We have indisputable evidence that the current state of things is not ergonomic; nobody uses call/bind/apply when an arrow function or unsafe call suffices.
from proposal-call-this.
Related Issues (20)
- Bikeshedding syntax HOT 98
- Compare and contrast with old proposals
- Need comprehensive review of why libraries use .call/.bind/.apply HOT 35
- Need better names for two types of method extraction HOT 4
- Suggestion: Loosen restriction on RHS of bind-this operator to allow dotted names HOT 6
- Optional chaining form HOT 2
- Invoking getter/setter behavior? HOT 38
- Collaborate with extension proposal HOT 15
- Ambiguity when `?.` in LHS? HOT 4
- Should we allow PrivateIdentifier after . in SimpleMemberExpression? HOT 1
- Typo in "README.md" HOT 1
- Erroneous .push usage statistics
- Broken link in README ("Formal specification") HOT 1
- TypeScript implementation
- Counter proposal: Function.prototype.call syntax HOT 14
- Interoperability with symbol-based protocols HOT 11
- Real-world examples from Node.js HOT 3
- Use case: Individually importable, tree-shakable methods HOT 5
- Motivation beyond defensiveness against mutation of globals? HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from proposal-call-this.