0

I am learning Javascript from udemy and in one lecture tutor has implemented a function using bind() method, however when i am trying to use call() it doesn't work.

Here is a small program that works with bind:

function mapForEach(arr, fn){
    var newArr = [];
    for (var i=0; i < arr.length; i++){
        newArr.push(
            fn(arr[i])
        )
    };

    return newArr;
}

var arr1 = [1,2,3];

/* trying to compare if the item is greater than given limiter*/
var checkPastLimit = function(limiter, item){
    return item > limiter;
}

/*bind both functions and check if item is greater than 1*/
var arr4 = mapForEach(arr1, checkPastLimit.bind(this,1));
/*print array in boolean*/
console.log(arr4); 

-----
Output: [false,true,true] 

This program works as I want, however how can i use call() or apply() method here instead of bind? I am trying from yesterday but not getting what i want.

What I tried

I tried following documentation on mozilla's offical page, however I don't get the desired output.

I tried editing the checkPastLimit function like below:

var checkPastLimit = function(limiter, item){
    mapForEach.call(arr1, checkPastLimit(this,1));
    return item > limiter;
}

console.log(checkPastLimit);

but this code throws recursion problem.

I also tried another trick but it didnt worked too

var checkPastLimit = function(limiter, item){
    return item > limiter;
}

mapForEach.call(arr1, checkPastLimit(this,1)); 

What I Want

The working program listed above generates the desired output using bind(), but i want to get the output using call()

[false,true,true] //if 1 is limiter

[false,false,true] // if 2 is limiter

2 Answers 2

2

bind and call (or apply) are not really alternatives for the same thing. bind returns a function, while call executes a function. The only thing they have in common is that they allow to specify what this should be. But in your actual case the value of this is not used, so that common part is not relevant.

In your working code the bind method is used to create a curried function on-the-fly, i.e. it creates a new function that takes one argument less, since the first argument is fixed to be the value 1. This is called currying.

If you want to do this without bind then you really are going to implement your own version of bind (specific to this case). It could for instance look like this:

// Create this additional function, which returns a function(!) with one less argument.
var curriedCheckPastLimit = function (limiter) {
    return function(item) {
        return checkPastLimit(limiter, item);
    }
}

var arr4 = mapForEach(arr1, curriedCheckPastLimit(1)); // No more bind!

Or you could drop the currying pattern and just do this (using an arrow function with expression syntax):

var arr4 = mapForEach(arr1, item => checkPastLimit(1, item));

As a side note: your mapForEach function already exists as a native array method:

var arr4 = arr1.map(item => checkPastLimit(1, item));
Sign up to request clarification or add additional context in comments.

3 Comments

your solution works but its little difficult to digest as a beginner. so as far as i understood i can only execute it using bind currying method or no bind. This is very confusing but thanks i am trying to understand it.
Let me know how I can help. I agree that currying is not beginner's stuff.
i tried this program in ide and slowly tried to understand what this is doing. because there is a function returning a function which is returning another function, it looks so confusing. but i am getting it little by little. just trying to connect all the dots, however i shall accept your answer. thank you very much
1

The function mapForEach accepts a function as second parameter.

When you call checkPastLimit.bind(this,1) it returns a function as result.

When you call checkPastLimit.call(this,1) it returns false.

So you can't simply use call instead of bind

enter image description here

1 Comment

yes i understood that. as per comment above it seems i cannot use call just as i used bind

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.