3

I read this blog post recently: The Two Pillars of JavaScript Part 1: How to Escape the 7th Circle of Hell, which is essentially a criticism of object oriented programming, and advocacy for funtional programming instead.

Some key points made:

  • Constructors violate the open/closed principle because they couple all callers to the details of how your object gets instantiated. ... JavaScript doesn’t need constructor functions because any function can return a new object. With dynamic object extension, object literals and Object.create(), we have everything we need — with none of the mess. And this behaves just like it does in any other function. Hurray!

  • Classical Inheritance generally lets you inherit only from a single ancestor, forcing you into awkward taxonomies. I say awkward because without fail, every OO design taxonomy I have ever seen in a large application was eventually wrong.

  • The coupling between a child class and its parent is the tightest form of coupling in OO design. That’s the opposite of reusable, modular code.

    Making small changes to a class creates rippling side-effects that break things that should be completely unrelated.

Ok, sure. Without discussing the merits of these arguments (I think the article could do with some code examples) - how is this functional/prototype hacking paradigm used in practise?

ie. Particularly in regards to a framework like Angular or React - where the foundation of components are ES6 classes that extend a framework parent class.

5
  • 2
    You might be interested in React's 'stateless functional components'. I can't comment on Angular.
    – jasonk
    CommentedSep 6, 2018 at 4:06
  • @jasonk Sure - React has stateless functional components, but it's hard to know how you would create a button that knows how many times it has been clicked with it.CommentedSep 6, 2018 at 4:20
  • see Discuss this ${blog}
    – gnat
    CommentedSep 6, 2018 at 9:52
  • you'll have to find some functional programming advocates.....
    – Ewan
    CommentedSep 6, 2018 at 12:36
  • @dwjohnston, you cite Classical Inheritance, but JavaScript inheritance works on prototypal inheritance which works a bit differently than classic inheritance.
    – Daniel
    CommentedNov 24, 2018 at 19:17

1 Answer 1

4

In my previous role we were using mostly pure functions in React. Remember that React is a "library for building user interfaces". Often I see React projects where components are very object-oriented and encapsulate state, behavior, UI, and even style. There is a tradeoff to be made. When you encapsulate all those things in the component, you arguably get better readability, but you lose flexibility, reusability, testability, and loose coupling.

For starters I recommend you separate all behavior out of React components and inject the behavior through component properties. You can then define all your behavior as pure functions as well--even stateful behavior. Check out Recompose for a bunch of higher-order components that help keep functional when dealing with component state and Redux for application state.

As a concrete example, let's consider a button that increments a counter. With object-oriented components, you might write something like:

class Counter extends React.Component { constructor(props) { super(props) this.state = { counter: 0, } } render() { const { counter, } = this.state const onClick = () => { this.setState({ counter: counter + 1, }) } return ( <button onClick={onClick}>Val {counter} click to increase</button> ) } } 

With functional programming we would write it like so:

// pure functional component const Counter = ({ onClick, counter, }) => ( <button onClick={onClick}>Val {counter} click to increase</button> ) // elsewhere define the behavior again as pure functions const FunctionalCounter = Recompose.withStateHandlers({ counter: 0, // our initial state }, { onClick: ({ counter }) => () => ({ // a pure function that takes state, props, and parameters and updates state counter: counter + 1, }), })(Counter) 

Angular is a completely different beast because it's not a UI library, it's a "front-end web application framework" and it imposes a lot of constraints on how you write your applications. I'm unfamiliar with how one would write an Angular application with functional programming, but you can apply the same principles that I've done with React. Specifically, separate your behavior and business logic out of the UI into thoughtfully organized functions that are injected into the UI (i.e. you could use Angular's dependency injection to inject your business logic functions). It's generally a good idea to do this anyway so that your application logic is not coupled to a UI framework.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.