7 ms·
In almost 10 years of professional development with Javascript/Typescript, I have never encountered a colleague using the call/bind/apply keywords (or "this" ou
by Veuxdo 4y ago
In almost 10 years of professional development with Javascript/Typescript, I have never encountered a colleague using the call/bind/apply keywords (or "this" outside of classes). I'd say almost all professionals deliberately avoid 80%+ of the language in practice.
- Tcepsa 4y agoAs someone who likes functional programming, I appreciate .bind as a reasonably convenient way to do partial function application.
- golergka 4y agoOne thing I didn't get about functional programming is planning the parameter order in advance for currying them later. Arrow functions may not look as neat as Haskells currying, but you can partially apply any parameter regardless of whether it's first or not, including separate properties of object parameters.
- gherkinnn 4y agoDefaulting to data-last gets you 80% of the way. fn = (a -> b) -> a So your typical array mapping becomes list.map(to(v => v * 2)) All very contrived of course. Ramda’s currying [0] gives you the _ param to play with the order. But I’ve come to the conclusion that currying in JS is rarely worth the effort. [1] 0 - https://github.com/ramda/ramda/blob/v0.28.0/source/__.js https://github.com/ramda/ramda/blob/v0.28.0/source/__.js 1 - https://2ality.com/2017/11/currying-in-js.html https://2ality.com/2017/11/currying-in-js.html
- robgibbons 4y agoThey are very useful at the framework level, if you do much work with vanilla JS at scale they become useful for applying generic functions against various scopes.
- phist_mcgee 4y agoWhich makes reading framework code so much harder IMO. There are many constructs in good framework code that you very rarely see as a 'regular' JS developer. Sometimes even understanding where the entrypoint really begins in node_modules can be a challenge.
- emteycz 4y agoNot every tool a language offers should be used in your normal day-to-day dev work. Doesn't mean it's useless. I'm writing a dependency-less CLI tool with Node and just have used apply - super helpful ;-) I've also used it a lot when I wanted a dependency-less GraphQL server...
- umvi 4y agoI'm currently working on a game[0] similar to Untrusted[1] and I had to use bind (among other techniques like variable shadowing) in order to "sandbox" player provided code from interfering with other game objects or accessing the global scope (obviously there's no perfect sandbox, but it at least it makes it more difficult for players to do naughty things). Bind is useful because you can control the meaning of "this" when evaluating user-provided code, and I use it to deny player access to the parent scope by calling bind(undefined). [0] https://www.bryanpg.com/games/pragma_twice https://www.bryanpg.com/games/pragma_twice [1] https://github.com/AlexNisnevich/untrusted https://github.com/AlexNisnevich/untrusted
- tim1994 4y agoHave you considered running "untrusted" code in a worker? That way the code can not interfere with the global scope.
- umvi 4y agoIndeed, however, I started this project a few years ago before I knew about workers and so it would be a lot of effort to switch now. Perhaps if I make a follow on game I'd try workers. I'd have to implement message routing in order for objects to communicate with each other and I'm not sure how much impact that would have on performance.
- eBombzor 4y agoWhich is great. Mozilla does the same thing with C++. No reason to use complex footguns for simple tasks. Obviously there are use cases but mostly not for 90% of CRUD front end devs.
- arinlen 4y ago> Mozilla does the same thing with C++. To be fair, C++ is the epitome of a language you only adopt after consciously picking a very specific subset of features, or explicitly marking features as verboten. Template metaprogramming and exceptions are perhaps two of the most popular features that are routinely banished from C++ projects.
- serial_dev 4y agoI also deliberately avoided using them as they (IMO) belong to the "bad parts", or at least the parts that most mortal frontend devs don't need to use outside of interviews. With frameworks, it's easy to avoid them and unless you write lots of vanilla or you roll your own framework, they just don't come up, and therefore I expect my colleagues (and me) to just mess things up when we try to use them.
- cxr 4y agoRelevant: "How (and why) developers use the dynamic features of programming languages" <https://doi.org/10.1007/s10664-012-9203-2 https://doi.org/10.1007/s10664-012-9203-2> <https://users.dcc.uchile.cl/~rrobbes/p/EMSE-features.pdf https://users.dcc.uchile.cl/~rrobbes/p/EMSE-features.pdf>
- dmux 4y agoThanks for sharing this! In the last couple of years I've moved from being primarily a Java developer to a nodejs developer and I love exploring what dynamic languages bring to the table.
- cxr 4y agoI'm not sure that attitude is the right takeaway from the paper I linked.
- igouy 4y ago""How (and why) developers use the dynamic features of programming languages: the case of smalltalk"" https://www.inf.unibz.it/~rrobbes/p/EMSE-features.pdf https://www.inf.unibz.it/~rrobbes/p/EMSE-features.pdf
- Jasper_ 4y agoYeah, `call` got supplanted by `bind`, and `bind` got supplanted by arrow functions. `apply` got supplanted by spread parameter syntax. I've used them before for doing stupid reflection hacks (literally just used them today to build a debug UI where I can make sliders out of objects), but it's not code I would really want to ship in production.
- 29athrowaway 4y agoNo. Bind creates a new function, call and apply do not.
- osrec 4y agoMore specifically, bind creates a new function + context, that you can hold a reference to and reuse, but you cannot do this with call or apply.
- singlow 4y agoIn practice though, many places that used apply/call tend to bind instead.
- 29athrowaway 4y agoapply and call invoke a function with a specified receiver object, and arguments. bind creates a new function that is bound to a specified receiver.
- singlow 4y agoOne of the most common places front-end devs encountered call/apply was when binding functions to event handlers. In those cases an anonymous function was often generated which used apply or call. Bind replaces this dance for many cases. Hence, most cases where devs encountered js call/apply were replaced by bind. There are differences between the two, but they largely didn't matter for most cases.
- jollybean 4y agoKudos to the author ... ... but yes - a 'Modern' approach means calling out risks, or more abruptly - that which may even be considered 'anti pattern' inherent in a language as it evolves over time, with hindsight. Perhaps the most preeminent example would be pointers in C++ - which we generally know to use with 'smart pointers'. If C++ 'were designed today' - among other things, it'd be likely that 'smart pointers' would be 'default' and they'd be more deeply and seamlessly integrated, and 'direct memory reference' would be seen as a 'thing to do only if necessary' and a bit of a 'corner case'. Necessary, and common enough, surely as in that level of programming we are going to 'go there', however, it's something we wouldn't see as normal practice, rather something we do but with some other idioms, APIs and conventions around it ... possibly with demarcations of 'unsafe' a bit like Rust. I think it's important, because these are precisely the things that young developers may become entangled in. It should be more like: "By the way this is how this works, but you may want to think twice about using it, here are some cases where it might be 'ok', here are some cases where it's not". But I don't want to take away from good authorship either, we depend a lot on people stepping up to the plate and doing this work. As an aside, it seems almost perverse that 'Big Corps' just don't do this themselves. I mean, if AWS uses JS extensively, it'd seem reasonable (even from a selfish perspective) for them to 'just do' a comprehensive, JS set of docs. It's weird that the world depends on 'a few nice dudes/dudettes' to maintain something like 'caniuse.com' and the plethora of other such important works.
- UncleEntity 4y ago> Perhaps the most preeminent example would be pointers in C++ - which we generally know to use with 'smart pointers'. Smart pointers are nice and all that but I have yet figured out how to mix them with code which doesn’t use them which is like 99.9% of all library code. Not to mention that interfacing with C code (like python extensions) are basically impossible unless the calling code is responsible for the object lifetimes. I don’t know how language de jour deals with this C interop but have read it is a pain point almost universally. Even some of the newer languages I see posted here have manual memory management as the default.
- hoseja 4y ago
- wruza 4y agoWhich issues do these methods cause?
- wonderbore 4y agoNone. It’s just the GP is somehow complaining that just because they didn’t see them they’re not useful. I saw .call just a few hours ago because until recently it was the safe way to call hasOwnProperty[1]. 1: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#using_hasownproperty_as_a_property_name
- quickthrower2 4y ago.bind seemed to be an idiom in early React before we had the arrow functions. I also remember it coming up a bit in older frameworks like Knockout.
- code_runner 4y agoUsed bind a whole bunch in the knockout days and you will still find bind in a lot of todays react docs if I’m not mistaken.
- acemarke 4y agoDefinitely not "a lot" - searching the existing docs, I see a mention in the FAQ at https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-... , but not really elsewhere. Also, the new React beta docs at https://beta.reactjs.org https://beta.reactjs.org teach function components rather than classes, and thus there's no use of `.bind()` at all.
- LocalPCGuy 4y ago.bind doesn't really have a lot to do with frameworks specifically, except maybe just that the docs may have been the first time folks were introduced to those features of the JS language. That said, I did use it a TON in the jQuery days (event handlers).
- pronlover723 4y ago80%? Really? I don't feel like call/bind/apply are 80%. More like 1%. What's the 80% of unused features you're referring too? Now, not using 1% of a language seems common. There are plenty of parts of C, C++, C#, Java, Python, etc that I rarely run into. On the other hand, for testing, mocking, polyfilling, etc call/bind/apply are invaluable.
- Veuxdo 4y agoRe-reading the table of contents of this tutorial, no, probably not 80%. But if it isn't 50% it's close.
- onion2k 4y agoOn the other hand, for testing, mocking, polyfilling, etc call/bind/apply are invaluable. For writing libraries to do those things call/bind/apply are useful, but most developers aren't doing that very often.
- osrec 4y agoYeah, because they're probably using libraries that are heavily using those keywords under the hood, in order to supply functions with the correct 'this' context.
- lolinder 4y agoThat doesn't change the fact that if you're not a library author you should probably avoid using that feature. It's not that the feature shouldn't exist, it's that it's now best used in plumbing code, not in application code.
- ehnto 4y agoI think you are imagining a dichotomy of use cases that doesn't really exist. Not everyone is writing software by gluing libraries together, and so there are still plenty of uses for it outside of libraries.
- jb3689 4y agoThis used to be super common when events were more widely used
- Kiro 4y agoI highly doubt that. All of those used to be extremely common before arrow functions.
- conradfr 4y agoYou used them when your framework/library documentation or SO told you to, but way less deliberately.
- pkrumins 4y agoI concur. I have been programming JavaScript for 20 years and I have never used call/bind/apply. I have never been able to understand what they are for or what they do.
- AltruisticGapHN 4y agoA lot of laziness has come from these newer rest/spread syntaxes (something to do with functional programming patterns too?). As a oldschool Amiga/PCDOS/ASM/C developer who moved on to the web ten years later... it always feels awkward to me to do things like arr = [...arr, ...arr2] because I'm always wondering just how effectively that is handled by the Javascript compiler.
- wruza 4y agoOn a technical side, ubiquity of javascript ensures that performance of common cases will be looked at and improved, if not yet. But as a fellow former low-level, my humble advice is: stop worrying and write clear code. Clear code eventually will run fast and stay clear. Nuanced code eventually will run as fast but stay nuanced.
- code_runner 4y agoReadability and pragmatism always win.
- eurasiantiger 4y agoProbably more effectively than anything you could roll yourself.
- code_runner 4y agoThis used to be much more common in es5. It’s good to know how they work etc and why they were a necessary evil way back when.
- LocalPCGuy 4y agoAs someone that uses them from time to time, I have then had to then explain to colleagues what they are doing (and yes I consider this when I use it, whether that is worth the tradeoff). Personally, I like to extract larger arrow functions and I am a fan of traditional function declarations in some situations over `const x = () => {}` style function assignment (I feel the latter unnecessarily clutters up code above the logic of the specific component, service or module since it must be declared prior to being used.) Those preferences do lead to needing an understanding of bind, call and apply. Or maybe understanding bind, call and apply lead to me feeling comfortable using those patterns? Edit to add a bit of history: I started doing this when writing a fair amount of jQuery with a lot of event handlers. And while anonymous or arrow functions worked, the code was soo much cleaner when you put the handler functions below the regular logic. If someone wants to see what a handler function does, it's easy to go down and look, but otherwise, a good name is all that is important. These days, I follow similar patterns, extracting code that doesn't need to be inline into a function that can be referenced as needed, but doesn't need to be inline in the code all of the time.
- corderop 4y ago> I'd say almost all professionals deliberately avoid 80%+ of the language in practice. I don't think is a specific thing of JS. The same happen with almost any language, product features...