RMT
RMT

Reputation: 1162

Spread syntax ecmascript

I've used spread syntax before, but not in this way. I am confused over the jump between (...fns) to (...args). I understand that fns is the functions that are passed in (internalOnLoad and onLoad), and that the args are the arguments which belongs to the corresponding function. But how would it look like when each function are passing their arguments to the function (...args) => fns.forEach(...) ?

const callAll = (...fns) => (...args) => fns.forEach(fn => fn && fn(...args));

const internalOnLoad = () => console.log("loaded");

const Avatar = ({ className, style, onLoad, ...props }) => (
  <img 
    className={`avatar ${className}`}
    style={{ borderRadius: "50%", ...style }}
    onLoad={callAll(internalOnLoad, onLoad)}
    {...props} 
  />
);

Avatar.propTypes = {
  src: PropTypes.string.isRequired,
  alt: PropTypes.string.isRequired,
  className: PropTypes.string,
  style: PropTypes.object,
  onLoad: PropTypes.func
};

Can you give me a visual description of how this would look like? E.g. that calling callAll = (...fns) like this: callAll(internalOnLoad, onLoad) is the same as callAll will receive the arguments like this callAll = (internalOnLoad, onLoad)

Thank you in advance

Upvotes: 5

Views: 298

Answers (2)

K..
K..

Reputation: 4223

const callAll = (...fns) => (...args) => fns.forEach(fn => fn && fn(...args));

The first ... gets all functions.

The second ... gets all arguments.

The third ... inserts the arguments with fn.apply(undefined, args) into the function instead of fn(args).

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 191976

The rest parameters syntax collects all arguments into an array. In this case partial application is used to store an array of functions (fns), and return a new function. When the new function is called, it will invoke the functions in fns, and pass the arguments (args) to each one of them.

If we use the standard JS functions, it would be:

function callAll(...fns) { 
    return (...args) {
        fns.forEach(fn => fn && fn(...args));
    }
}

Example:

const callAll = (...fns) => (...args) => fns.forEach(fn => fn && fn(...args));

const callFns = callAll (
  (a, b) => console.log(a + b + 10),
  (a, b) => console.log(a + b + 20),
  (a, b) => console.log(a + b + 30),
);

console.log(callFns); // you can see the function that was returned in the console.

callFns(1, 2);

Upvotes: 5

Related Questions