I've worked full-stack in javascript for many years, and I've written plenty of libraries and tooling. I've used call/apply/bind/this extensively and I understand them to a fault.
I would still remove them in favor of arrow functions and spreads. Unless you can show me any code which is pivotal to writing some tool which absolutely can not be done using the alternatives.
Yup in terms of patterns that are easier/harder to understand, I much prefer arrow functions over bind and map/forEach over apply. And explicit function parameters over call though how to replace call is often contextual.
It’s not that I inherently think call/apply/bind are bad (JS programmers should understand them), it’s just that they are old JS-isms and arrow functions/map/forEach/etc. follow pretty consistent conventions across multiple programming languages (readability) and with JS compilers you mostly don’t have to explicitly write JS in the old way any more.
It’s kind of like using malloc/variants in C++, you should be able to understand it, but you mostly shouldn’t need it in new code.
Detecting that a value is an Object as opposed to an Array/Arguments/etc (or more generally, reading the StringTag of a value) still requires a toString.call(value) AFAIK.
This is still used a lot in recursive polymorphic code like virtual dom, AST traversal, deep cloning, etc.
`Array.prototype.slice.call(arguments)` is a good example. In fact, I'm struggling to think why you would replace anything other than bind with an arrow function
EDIT: My example is bad, you could just `[...arguments]`
They can't be removed from the language, sure, but we can benefit by shunning the bad parts of the language, and using newer additions that are easier to reason about.
When's the last time you considered using a with(x){} block in JS? Would you still use var instead of let or const?
Quite a few years since I used `with` the last time. Not going back to that one.
`call/apply/bind` are normal functions though, not some fancy syntax construct, and `this` is important if you want to play with prototypes/Object.create, which is what you want to do if you found class syntax sugar lacking in features/extensibility/overrideability.
>I would still remove them in favor of arrow functions and spreads.
Entire Javascript needs to be removed in favor of some other language. It's literally garbage. Callback hells, prototypal inheritance, constant new features ala async/await, Promises and a new framework every 2 years. It's not even a functional langauge just some features of functional language. Endless introduction of new syntactic sugar to cover up the old fuck-ups and weird behavior on every corner.
I hear this sentiment pretty often but don't really get it. New features like async/await and Promises are added so that we don't have to do things the old/bad/confusing way any more - isn't that a good thing? Tools like linters and Typescript make it much easier to avoid the various 'old fuck-ups' and 'weird behavior'.
There is something slightly demoralizing about writing JS as if because of the language itself there is cruft, ugly workarounds, and type confusion from day one instead of developing over time. That said I find it effective and doubt it will ever be replaced by a more pure clean language.
I would still remove them in favor of arrow functions and spreads. Unless you can show me any code which is pivotal to writing some tool which absolutely can not be done using the alternatives.