1

im kinda new at javascript so i have an function which is given an array and it filters its elements from the arguments it is passed. What i need though is to make 'this' inside the callback function to refference at my originalArray so that console.log(this); would acctually print [1,2,3]. Have in mind that i acctually need to this in these lines because i can only edit all those lines not add some more.

Here is my code:

function makeMultiFilter(array) {
    // What we track
    // TO BE COMPLETED
   // TO BE COMPLETED
    return (function arrayFilterer(pred, callback) {


        // If filter not a function return current Array
        // TO BE COMPLETED
            // TO BE COMPLETED
        // Filter out things
        // TO BE COMPLETED

        // If callback is a function, execute callback
        // TO BE COMPLETED
        // TO BE COMPLETED
            return arrayFilterer;
    });
}

And the test code:

var arrayFilterer = makeMultiFilter([1, 2, 3]);
// call arrayFilterer to filter out all the numbers not equal to 2
arrayFilterer(function(elem) {

    return elem != 2; // check if element is not equal to 2
}, function(currentArray) {
    console.log(this); // prints [1,2 3]
    console.log(currentArray);
}); // prints [1, 3]`
4
  • What is it your trying to do?. if you have an array and you want to filter out all that are not equal to 2, then this would do it -> theArray.filter(function (e) { return e != 2; }) , and even nicer if your can use ES6 -> theArray.filter((e)=>e != 2)
    – Keith
    Commented Oct 24, 2016 at 13:08
  • i cant change the test code as it was given to me like that, plus i cant adde more lines it is strictly the number of those you can see. The filtering seems to work just fine but the guide tells me that when accessing the callback function, 'this' should refer to originalArray and not the object window.
    – Dimiwiz
    Commented Oct 24, 2016 at 13:11
  • Look into .call and .apply. Commented Oct 24, 2016 at 13:13
  • I've searched almost everything for examples but i cannot find something to help me. I would be grateful if you can be more specific @FelixKling
    – Dimiwiz
    Commented Oct 24, 2016 at 13:22

1 Answer 1

2

You can use call to execute a function in a given this context:

var callback = function() {
  console.log(this);
  console.log(arguments);
};

// Using call
callback.call([1,2,3], "A", "B", "C");

// Using apply
callback.apply([1,2,3], ["A", "B", "C"]);

// Using bind:
//  creates a new function bound to [1,2,3]
callback.bind([1,2,3])("A", "B", "C");
callback.bind([1,2,3], "A")("B", "C"); // etc.

I guess that in your example code, that would mean that instead of doing callback(), you'd use callback.call(originalArray):

function makeMultiFilter(array) {
    // What we track
    var originalArray = array;
    var currentArray = originalArray;
    return (function arrayFilterer(pred, callback) {
        // If filter not a function return current Array
        if (typeof pred !== "function")
            return currentArray;
        // Filter out things
        currentArray = currentArray.filter(pred);

        // If callback is a function, execute callback
        if (typeof callback === "function")
            callback.call(originalArray, currentArray);
            return arrayFilterer;
    });
}

var arrayFilterer = makeMultiFilter([1, 2, 3]);

// call arrayFilterer to filter out all the numbers not equal to 2
arrayFilterer(function(elem) {
    return elem != 2; // check if element is not equal to 2
}, function(currentArray) {
    console.log(this); // prints [1,2 3]
    console.log(currentArray); // prints [1,3]
}); // prints [1, 3]`

5
  • Hello, if i insert callback.call(originalArray) in my code after the callback check, it would print [1,2 3] but console.log(currentArray); will print undefined
    – Dimiwiz
    Commented Oct 24, 2016 at 13:27
  • Also , the test cannot is as it is, it was given to me so that i can implement my code correctly, i cannot change it.
    – Dimiwiz
    Commented Oct 24, 2016 at 13:28
  • The first argument in call is the this context. All other parameters you provide will be passed to the function you're calling. Note that I didn't change the test code, I only replaced // TO BE COMPLETED by callback.call(originalArray, currentArray); Commented Oct 24, 2016 at 13:32
  • Yes, i just noticed. Thank you a lot, it worked! One last question, should console.log(array) and console.log(originalArray) print undefined ?
    – Dimiwiz
    Commented Oct 24, 2016 at 13:36
  • array and originalArray are defined in the closure of makeMultiFilter. They can only be accessed by functions that are defined within the same closure. The callback that is passed isn't, so it's expected that they print undefined when logged in the callback. Commented Oct 24, 2016 at 13:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.