简体   繁体   中英

How to use a variable in a callback function that is not available when the function is created

I am learning about functional programming in Javascript and I am running into an error on the below code. The error says that list is undefined. This is obviously coming from my filterVideos function because it uses list, but list has not yet been defined. I know I can just place the function into my return statement, but I am trying to keep the function separate from the return statement. So my question is, is there a way for me to declare the function before the list variable has been defined?

var myFunction = function() {
    var lists = [
            {
                "id": 5434364,
                "name": "New Releases"
            },
            {
                "id": 65456475,
                name: "Thrillers"
            }
        ],
        videos = [
            {
                "listId": 5434364,
                "id": 65432445,
                "title": "The Chamber"
            },
            {
                "listId": 5434364,
                "id": 675465,
                "title": "Fracture"
            },
            {
                "listId": 65456475,
                "id": 70111470,
                "title": "Die Hard"
            },
            {
                "listId": 65456475,
                "id": 654356453,
                "title": "Bad Boys"
            }
        ];

    var filterVideos = function(video){ return video.listId == list.id;};
    var mapVideos = function(video){return {id: video.id, title: video.title};};

    return lists.map(function(list) {
        return {
          name: list.name,
          videos: videos.filter(filterVideos).map(mapVideos)
        };
    });
}

myFunction();

You could change filterVideos so it generates a filtering function that has the list in scope:

var myFunction = function() {
    var lists = [{
            "id": 5434364,
            "name": "New Releases"
        }, {
            "id": 65456475,
            name: "Thrillers"
        }],
        videos = [{
            "listId": 5434364,
            "id": 65432445,
            "title": "The Chamber"
        }, {
            "listId": 5434364,
            "id": 675465,
            "title": "Fracture"
        }, {
            "listId": 65456475,
            "id": 70111470,
            "title": "Die Hard"
        }, {
            "listId": 65456475,
            "id": 654356453,
            "title": "Bad Boys"
        }];

    var filterVideos = function(list) {
        return function(video) {
            return video.listId == list.id;
        };
    };
    var mapVideos = function(video) {
        return {
            id: video.id,
            title: video.title
        };
    };

    return lists.map(function(list) {
        return {
            name: list.name,
            videos: videos.filter(filterVideos(list)).map(mapVideos)
        };
    });
}

myFunction();

As you say, the error is because list isn't defined at that point in the code. The two obvious solutions are either to either move it into a scope where it is defined (which you say you don't want to do), or pass it as a parameter to the filterVideos function so that it's available within.

Since you can't change the parameters that filter passes to its callback, the most obvious solution is to create a closure which defines the parameter and returns a function that has "list" in scope.

var filterVideos = function(list) {
    return function(video) {
        return video.listId == list.id;
    }
};
var mapVideos = function(video){
    return {id: video.id, title: video.title};
};

return lists.map(function(list) {
    return {
      name: list.name,
      videos: videos.filter(filterVideos(list)).map(mapVideos)
    };
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM