This syntax does not imply dependency injection, it just means one function is returning another. More explicitly, what is occurring is the following:
function Carregar() {
return function() {
};
}
However, this type of construction allows you to achieve some goals more easily due to the Javascript closures system. The above pattern also takes the factory function name or Factory Function in English, in which Carregar
is the factory. In this case, Carregar
is the factory function, which whenever called will create a new function, returning it.
Somehow, this pattern slightly resembles a class, which will create an instance of something. In this case, the Factory Function will always create a new function.
You can achieve several things with this kind of construction, like creating some kind of counter that maintains an internal and private state:
function createCounter() {
let current = 0;
function getCurrent() {
return current;
}
function increment(step = 1) {
current += step;
}
return {
getCurrent,
increment
};
}
const counter1 = createCounter();
counter1.increment(5);
counter1.increment(3);
const counter2 = createCounter();
counter2.increment(4);
console.log('Valor do contador 1:', counter1.getCurrent()); // 8
console.log('Valor do contador 2:', counter2.getCurrent()); // 4
Note that in the example above we no longer return a function, but rather an object with several functions. Note also that each counter has a different state, which is due to the Javascript closujes system. Each function has its own closure, which allows this type of state storage.
This can also be used as a way to achieve dependency injection into functions, so you use the higher function to pass the dependencies and the(s) function(s) returned(s) no longer need to receive this type of value in their arguments. See the difference:
// A nossa "dependência":
const consoleLogSender = {
send: (message) => console.log(message)
};
function sum(sender, a, b) {
const result = a + b;
sender.send(a + b);
}
// Para usar:
sum(consoleLogSender, 2, 2); // 4
sum(consoleLogSender, 3, 5); // 8
Now, with this pattern of Factory Function:
// A nossa "dependência":
const consoleLogSender = {
send: (message) => console.log(message)
};
function createSum(sender) {
return function sum(a, b) {
const result = a + b;
sender.send(a + b);
}
}
const consoleLogSum = createSum(consoleLogSender);
consoleLogSum(2, 2); // 4
consoleLogSum(3, 5); // 8
Note that the result is the same, but some people prefer this second way, mainly seeking a decoupled architecture, something in parts achievable by dependency injection.
Now, turning the Arrow functions, the above code can be written as:
// A nossa "dependência":
const consoleLogSender = {
send: (message) => console.log(message)
};
const createSum = (sender) => (a, b) =>
sender.send(a + b);
const consoleLogSum = createSum(consoleLogSender);
consoleLogSum(2, 2); // 4
consoleLogSum(3, 5); // 8
However, readability is compromised. I personally will always choose to use function statements in cases like this. In addition, Arrow functions do not have that goal. Sometimes people use something unnecessarily something just for finding "beautiful", which is the case there.
can put an example in your question?
– Ricardo Pontual