# freeCodeCamp - Functional Programming: Implement map on a Prototype - Question

freeCodeCamp - Functional Programming: Implement map on a Prototype - Question
0

#1

Hello,
i did the exercice “fine” but i have a question. How do you “genericly” recovers the array.map(…).

In this exercice we simply use the “s” in the prototype because “s” is a global variable. But it’s not generic. It will only work with a variable named “s” so the reusability is none. So how can you recover the array (here “s”) and use it genericly, so with any array name, in the prototype ?

``````
// the global Array
var s = [23, 65, 98, 5];

Array.prototype.myMap = function(callback){
var newArray = [];
for( let x = 0; x < s.length; x++ ) {
newArray.push( s[x] * 2 );
}
return newArray;

};

var new_s = s.myMap( function( item ){
return item * 2;
} );

console.log( new_s );
``````

#2

Actually, your solution could make use of the callback argument instead of hard-coding the formula of the function passed to the myMap. To not use the global variable s, you would use this. See below:

``````// the global Array
var s = [23, 65, 98, 5];

Array.prototype.myMap = function(callback){
var newArray = [];
for( let x = 0; x < this.length; x++ ) {
newArray.push( callback(this[x]) );
}
return newArray;

};

var new_s = s.myMap( function( item ){
return item * 2;
});
``````

#3

Hello, thanks you !
I don’t know how to use callback. And the “this.” is special in javascript. It was “easiest” to understand in Java.
I’m going to examin it.

But some thing i don’t like is it’s like it’s coming from nowhere in the “course” (the use of the callback+this).
As a studend, we have, i think, no background.

#4

@RandellDawson What does this refers to in this.length and callback(this[x]) ??

#5

`this` refers to the calling object. For example

``````const a = [1,2]
const b = [1]

Array.prototype.myMap = function (cb) {

// this.length = a.length when called like a.myMap
// this.length = b.length when called like b.myMap
return this.length
}

``````

#7

Callbacks are functions you pass into another function. So

``````function someFunc(x, callback) {

callback(x)
}
``````

Will run the callback function for me inside `someFunc`. So I can call it like this for instance:

``````someFunc("I'm logged by the callback", console.log)// "I'm logged by the callback"
``````

So you can think of someFunc looking like this when passed `console.log`

``````function someFunc(x, console.log) {

console.log(x)
}
``````

I’m not familiar with java, but according to the interwebs, `this` refers to the instance that the method is called on. This means in java `this` is referencing something internal.

In javascript, this refers to the execution context. This only means that `this` can refer to the instance when it’s called within itself, like in a class. But it can also bind to the calling object. Like how you see here

``````const a = [1,2]
const b = [1]

Array.prototype.myMap = function (cb) {

// this.length = a.length when called like a.myMap
// this.length = b.length when called like b.myMap
return this.length
}
``````

A safe(?) way to look at it is: `this` belongs to the caller of the function.

This isn’t always true, but in most cases it is.

#8

Question: I tried a solution very similar to this but instead of using the “this” keyword, I tried using “arguments” and it didn’t work. Why doesn’t “arguments” work here? What exactly is “this” referring to in this particular scenario?

#9

Using arguments inside the anonymous function would only have access to the argument named cb and not the array.

#10

My solution was the same however I first tried to use a for…in loop like so:

``````  for(let i in this){
newArray.push(callback(this[i]))
}
``````

however, this returns not only the array passed in, but also the methods in the prototype resulting in

`// [46, 130, 196, 10, NaN]`

A workaround could look like

``````  for(let i in this){
if(!isNaN(i)) newArray.push(callback(this[i]))
}
``````

but I’m not sure if this would produce weird results in other situations.
Just some food for thought about the difference in the types of for loops.

#11

This is because `for...in` iterates over all enumerable properties of the object. And in javascript, arrays are just objects with a few fancy methods attached.

If you only want to iterate over the items of the array, you have to use the `for...of` loop instead

It will, because `if(!isNaN(i))` explicitly checks only for non-numbers.

But if you were iterating an array of objects, you’d still have issues with checking those extra properties.

If you don’t want to use a `for...of` loop, you have to protect like this:

from mdn:

If you only want to consider properties attached to the object itself, and not its prototypes, use getOwnPropertyNames() or perform a hasOwnProperty() check

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

``````for (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
/* here we are safe */
}
}
``````

#12

Hey! So this worked for me, didn’t have to use much complicated solution, had a hard time grasping the concept of callback though.

// the global Array
var s = [23, 65, 98, 5];

Array.prototype.myMap = function(callback){
var newArray = [];
for (let i = 0; i < this.length; i++) {
newArray.push(callback(this[i]));
}
return newArray;

};

var new_s = s.myMap(function(item){
return item * 2;
});

#13

Sorry guys , I really don’t know why we use callback(this[i]));

#15

You can’t do like this, because your map should give a result depending on a callback it receives. For example what if I would like to get new array of squared values? so you need callback to make your map universal.

#16

The callback receives a value, and returns doubled value. So we use the callback to get doubled value and push to our array that we are going to return as a result

#17

As @NurbekGithub points out in his reply, the whole point of the challenge is to simulate the Array.prototype.map method. The map method uses a callback function to generate the new array. All you have done is defined an array method which multiplies each element by 2 and returns the results in a new array. A true map method would allow you to pass in a function which would perform the multiplication by 2 or division by 2 or make any other modification to the original array’s values that you can dream up. You do not want to have to create a different method for each way you want to be able to manipulate the original array values. Instead, you want a single method which is reusable and applicable to any type of value manipulation which can be performed with a function.

#19

Solution “forEach”

`````` // Add your code below this line
this.forEach(function(item){
newArray.push(callback(item))
});
``````

#20

I am having a hard time with “callback” too, and sounds like a lot of people are having the same deal. Here’s my understanding:

``````
[quote="arzish, post:12, topic:156632"]
Array.prototype.myMap = function(callback){
// Here we are defining a function that takes an input "callback". My main question here is WTF is callback? Well, let's look further down the code.
var newArray = [];

for (let i = 0; i &lt; this.length; i++) {

newArray.push(callback(this[i]));
// OK, here's "callback" again. So we're asking our function to push a version of this[i] (a version that is modified by callback) to newArray. But still, WTF is fucking callback? (<- that, in essence is my frustration...)  Let's look further down:

}

return newArray;

};
// Here we are assigning stuff to new_s. That stuff is the result of myMap() with function(item) as an input. What does function(item) do? It returns item*2. So we are passing in a function that converts i to i*2 INTO the myMap() function. So when you ask yourself WTF is callback? It's an input to myMap that needs to be a function, and that function is none other than the function that we are defining below.
var new_s = s.myMap(function(item){

return item * 2;

});
[/quote]

type or paste code here
``````

#21

My solution with forEach

``````this.forEach( (el) => newArray.push( callback(el) ) );
``````

#22

I believe this is the expected code. The challenge should probably hint to that you should use “this” to complete the challenge.

// the global Array
var s = [23, 65, 98, 5];

Array.prototype.myMap = function(callback){
var newArray = [];
for (let i = 0; i < this.length; i ++) {
newArray.push(callback(this[i]) );
}
return newArray;

};

var new_s = s.myMap(function(item){
return item * 2;
});

console.log(new_s)

#23

Well, this was really confusing, managed to work out to use this, however, would of never have understood to use newArray.push(callback(this[i]) );

anyway, thanks to the forum, managed to work it out, but can’t say i fully understand it!