Since Javascript is a language where you don’t need to specify the type of data you expect to receive in the argument passed to the function (in this case you called the argument callback
) the code that uses this argument needs to make this check or else an error may occur when it is using this argument.
In your code, you expect the argument callback
is a function type variable and this function takes 3 arguments: the array element, the array index and the array itself. The code defines the signature this way because it was probably based on the method code forEach
.
Why are you doing it like that?
Why do you expect the user of this function forEach2
use it as follows: umArrayQualquer.forEach2(function (v, i, arr) { ... });
Thus, when used, the function will be passed in the argument callback
and internally will make the call to function correctly.
Javascript is smart enough that the user of its function can have a simpler signature like umArrayQualquer.forEach2(function (v) { ... });
and work without error your code that makes the call, but imagine that the user of your function does not use it in this way. If he makes the call like this: umArrayQualquer.forEach2(123);
. Instead of passing a function that expects 3 arguments, you passed a number. This will cause an error in your code.
Array.prototype.forEach2 = function (callback) {
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this)
}
}
var umArrayQualquer = [1, 3, 4];
console.log("com função completa");
umArrayQualquer.forEach2(function (v, i, arr) {
console.log(v);
});
console.log("com função simplificada");
umArrayQualquer.forEach2(function (v) {
console.log(v);
});
console.log("com argumento errado");
umArrayQualquer.forEach2(123);
For this reason, whenever you are extending a class it is important to make checks within the code to ensure that the user of your function does not cause an unforeseen error.
Array.prototype.forEach2 = function (callback) {
if (typeof callback === 'function')
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this)
}
}
var umArrayQualquer = [1, 3, 4];
console.log("com função simplificada");
umArrayQualquer.forEach2(function (v) {
console.log(v);
});
console.log("com argumento errado");
umArrayQualquer.forEach2(123);
Of course, I set a pretty extreme example and since you probably would make use of its extension yourself, you wouldn’t make that kind of mistake when using it, but I put it here just to illustrate that it is important you do checks to avoid errors because of this lack of Javascript typing.
You would need to always do so, passing the same values as the forEach
gets? No. As you are extending the Array class you can set the arguments the way you need to suit your need. If you are extending because your code will be used by other people, then it is interesting to maintain the standard because the user of the code will expect a different version of a forEach
has similar usage characteristics.
The name you give to your function is also important. If you call forEach2
is a good tip for those who will use understand that is similar to a forEach
, and if you implement with something completely different you will be disturbing who will use the function. So a tip is whenever you extend an existing class try to study the class first, what methods it has and how they work, especially so you don’t reinvent the wheel.
You do not necessarily need to pass three parameters, you can pass as many (and which) you want, also you can pass only the ones you will use.
– Leonardo Santos
Thank you @Leonardosantos. E in this case the callback used three parameters because they are all attributes needed to return the loop value for (value, index, and Array itself), that?
– Ricardo