Comments on Making your JavaScript Pure

21 Reader Comments

Back to the Article
  1. <code class=" language-javascript">
    function setElementBackground(id, color) {
        document.getElementById(id).style.backgroundColor = color;
    }
    
    setElementBackground('foo', 'red');</code>
    Copy & paste the code below to embed this comment.
  2. I’ve never heard this referred to as “pure functions” before. In other languages it’s known as dependency injection. Often dependency injection is at the class level, but it applies just as much at the function/method level.

    Good read :-)

    Copy & paste the code below to embed this comment.
  3. I’ve never heard of this as “dependency injection”. In fact, it’s a pretty big misunderstanding of what each term denotes (pure/impure and dependency injection).

    The authors definition in the first section is absolutely correct.

    Copy & paste the code below to embed this comment.
  4. Pure functions don’t depend on anything that’s not passed in, or in other words, injected. Same concept. You can’t achieve purity if you don’t pass in all the dependencies.

    I’m not arguing that the author is wrong in any way, I was just noting that it’s interesting how similar concepts are referred to differently in different language contexts.

    Copy & paste the code below to embed this comment.
  5. People are going to argue over what the definition of “pure” means, as seen when people start talking about side effects of mutability. We’re really talking about inversion of control using dependency injection (i.e. you pass everything the function needs into the function versus the function reaching outside itself for anything).

    It’s a great technique everyone should know.

    Copy & paste the code below to embed this comment.
  6. @jack: A function, that does not return a value is called a method. A method cannot be pure, because its result is always `undefined` and is usable only for it’s side-effects, therefore not pure. What’s missing in your definition is mention of side-effects, like mutating the DOM, or performing I/O (like AJAX, or `console.log`).

    (well, technically function() {} is a pure function, but you can just replace its result with `undefined` because of referential transparency).

    There’s a trick to make any function pure: instead of performing side-effects, make it return a function (functions are first-class in JS), that performs side-effects, e.g.

    function changeColorFactory(id, color) {
      return function() {
        document.getElementById(id).style.backgroundColor = color;
      }
    }
    

    Remember that you can return also a list or object for multiple return values, which is even elegant to consume using ES6 destructuring. This way, it’s possible to structure a program to perform side-effects (returned functions from pure functions) from a single place and test 100% all the rest of it. Such strict separation is probably rarely practical, just mentioning it as an extreme.

    You can also do automatic testing of pure functions, see Haskell’s quickcheck.

    Dependency injection is just passing a function as a parameter to another function. This is usable to isolate side-effects performing functionality and easily mock it for testing. So:

    function changeColor($document, id, color) {
      $document.getElementById(id).style.backgroundColor = color;
    }
    
    mock = createMockDocument('getElementById', ...); // returns a document object, that asserts a method is called, it returns a certain object, which contains a setter property, which is called with certain parameters (implementation is rather lenghty and far from trivial, hence skipping)
    
    changeColor(mock, 'foo', '#00C0D3'); // mock's machinery kicks in and asserts all is as expected
    

    All examples in this article and my comment are simple enough to look contrived, but’s *invaluable* to be able to make robots test for you more complicated codebase, and most codebases tend to grow and complicate.

    Copy & paste the code below to embed this comment.
  7. When a function changeElementToRed(elem) updates the DOM it’s really a bit silly to call that a “side effect” - the whole purpose of the function is to update the DOM, so when it does so that is the desired effect. (You can argue that it isn’t “pure” because it mutates something, and that’s fine - I’m just saying that the term “side effect” is ridiculous in that context.)

    Copy & paste the code below to embed this comment.
  8. please, delete my upper comment, something is wrong in the interaction with my browser and ALA :(

    As I said, all code examples here are contrived, that’s why “side-effect” looks silly to you. But there are whole languages, which are very strict in the way they allow you to perform side-effects thus catching a huge class of JS-would-be-bugs on the compiler level.

    Now imagine a function, that does an AJAX call, then does a complex, lengthy transformation on the received data and then sets innerHTML of some element, to bring a more real-world example.

    In this case it makes sense to extract a pure function, that accepts an object and returns an HTML string. You can easily test this function:

    const inputs = [{input1}, {input2}, ...];
    const expectations = ['expected result 1', '..', ...];
    
    const testsPass = inputs.every((input, index) => myPureTransformator(input) === expectations[index]);
    console.log(testsPass ? 'yep' : 'nope');
    

    and perform your side-effects outside the function:

    fetch(URL).then(response => document.getElementById()[removed] = sanitize(myPureTransformator(response)));

     

    Copy & paste the code below to embed this comment.
  9. Me neither ever heard of “dependency injection”.  But I agree, this is a technique that is good to know!

    Copy & paste the code below to embed this comment.
  10. Back in the day it was very easy to just reuse some old scripts on new sites. But we soon found out that not only does this not future proof the site but it becomes a nightmare to debug.

    Making Javascript ‘pure’ like you say definitely helps and so this article resonated with me as the points made are valid and make a lot of sense. Thanks for sharing.

    Copy & paste the code below to embed this comment.
  11. Very usefull article, it will save me lot of time. Thanks!

    Copy & paste the code below to embed this comment.
  12. Dependency Injection is probably not well-known in JS or HTML development, but it’s quite popular in lower-level language like Java or .NET.

    Also I think method is nothing about not returning a value. Method usually means a function member of a class (in OOP-sense, not CSS), or object.

    Copy & paste the code below to embed this comment.
  13. mr_tawan and knagurski: Knowledge of functional purity and dependency injection have less to do with the level of programming language developed in, and more to do with the programming paradigm the developer subscribes to.

    If you subscribe to the test-driven development paradigm, you will likely know about dependency injection. If you have used functional programming languages like F#, Haskell, or some Lisps, you will know about functional purity.

    Both dependency injection and functional purity are important concepts to understand, but they are not identical. For a function to be strictly pure, it has to only use variables supplied by it’s input, it can’t modify the variables it has been supplied, and it can’t have side affects, meaning that it can only return a value and cannot perform actions that affect the state of the system it runs on.

    As you can see, there is some overlap between this and dependency injection, but the concepts are definitely distinct.

    Copy & paste the code below to embed this comment.
  14. javascript is just a basic one niw they got their higher versions like node js, angular js so we need to learn new one alsoangularjs tutorial snapchat pc

    Copy & paste the code below to embed this comment.
  15. Javascript is most important programming language which is allow to attract user to visit your website. you should use the javascript code for action of website to make more attractive.

    Copy & paste the code below to embed this comment.
  16. information about javascript code that is very helpful for me who is studying deeper .. keep working , thanks to quality article , if you need information about more try visiting..Harga cat semprot motor

    Copy & paste the code below to embed this comment.
  17. Thank you for this information, but this always works? I mean can you use this if your site is hosted on blogger? I have to try it. Thank you

    Copy & paste the code below to embed this comment.
  18. “In JavaScript it’s very hard to write pure functions that do manipulate the DOM (without using a React-esque library)”

    I strongly disagree. It’s not hard (well, technically, it’s impossible, because JS isn’t pure period, but for the perfectly workable purposes of “pure” in a JS context), and certainly no harder than in other languages (heck, pure FP languages like Haskell took YEARS to settle on a principled way to do it, not because of the pure part, but because of the manipulation part!) and it certainly doesn’t require behemoths like React (React is literally not pure from the get go, when you React.render!).  JS, on the other hand, had the ability to create pure functions that described effects on day 1!

    To write a pure JS function that manipulates the DOM, you just need an extra layer of execution delay above the layer that describes the manipulation.  People do this all the time without realizing it whenever they write functions that use closures or create thunks. Take a function that accepts a selectorString and then returns a function that _will_ retrieve that string the _next_ time it’s called.  That’s a pure function, because when you call it, you always get back a function describing the same operation.

    On a more structured level, it’s also possible and not that hard to create a type interface like IO which allows you to compose entire sequences of functions in a pure way, even if they have effects.

    Copy & paste the code below to embed this comment.
  19. Here’s a gist laying out the basic IO approach I’m talking about, along with some helpers for Arrays/Promises that make it pretty easy to describe dom-traversal and mutation all without running the effect (at least until it comes time to explicitly run it).

    Copy & paste the code below to embed this comment.
  20. Real benefit is in Object manipulation. Without pure functions, at some point, you can easily override some property without even knowing that.

    Copy & paste the code below to embed this comment.