-1

Curried functions gets cached by the compiler (some guy)

This component below has two buttons, one calls a function which returns the onClick handler, the other does the same, but inline.

According to my knowledge, both are doing the same thing, they are creating a new function () => this.foo() on each render() call. Someone said that the curried function version is cached and optimized by the compiler, so there is a benefit compared to the inline version. I think its the exact same thing and the guy who wrote this wanted to conceal an inline function with that expression.

class MyComponent extends Component {
  foo = () => console.log('fooo')

  getFunction = callback => {
    return () => callback();
  }

  render() {
    return <div>
      <button onClick={this.getFunction(this.foo)}>curried function</button>
      <button onClick={() => this.foo()}>inline function</button>
    </div>
  }
}

I did some googling, but could't find a proof/disproof to the statement, what do you think guys?

a better oliver
  • 26,330
  • 2
  • 58
  • 66
webdeb
  • 12,993
  • 5
  • 28
  • 44
  • I might be missing something, but... where's the currying here? Also, this is not JavaScript (nor es6) - you might want to tag also with [tag:jsx]? – Amadan Feb 10 '17 at 04:35
  • In getFunction() ? – webdeb Feb 10 '17 at 04:38
  • From Wikipedia: "In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument". Your `foo` is a nullary function, so I can't wrap my mind around how you think currying is being done. Are you using some alternative meaning of "currying"? – Amadan Feb 10 '17 at 04:40
  • There is an es6 tag – webdeb Feb 10 '17 at 04:41
  • 2
    There is. I am saying this is not ES6. `return
    ...
    ` is not in ES6 spec (but it is in JSX). Meanwhile, declaring methods using `=` is, AFAIK, neither ES6 nor JSX.
    – Amadan Feb 10 '17 at 04:46
  • It is, you can call foo also like 'getFunction(foo)()' – webdeb Feb 10 '17 at 04:46
  • Right its es2016 stage 1 I guess – webdeb Feb 10 '17 at 04:47
  • Where is that statement from? Please cite its source! *(And also, who says "gecached"…)* – Bergi Feb 10 '17 at 04:50
  • Oh its german, updated! – webdeb Feb 10 '17 at 04:52

1 Answers1

1

No, they're not doing the same thing; the getFunction one does call its callback without a this context. Of course, for the particular foo arrow function it doesn't matter at all.

Yes, both of these create a new function on every render call. The code of the respective closure would be cached, but the function object and its lexical context are not.

To avoid this, use the foo function itself (without any wrappers), which is created only once in the constructor:

class MyComponent extends Component {
  constructor(...args) {
    super(...args);
    this.foo = (e) => console.log('fooo');
  }
  render() {
    return <div>
      <button onClick={this.foo}>cached function</button>
    </div>
  }
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375