Метод не добавляется в прототип - PullRequest
0 голосов
/ 05 мая 2018

У меня есть файл JS, который я использую для изучения JavaScript. Однако когда я запускаю concatAll, он говорит:

Uncaught TypeError: movieLists.map(...).concatAll is not a function

Файл Js:

console.log(tryFun());

Array.prototype.concatAll = function() {
    var results = [];
    this.forEach(function(subArray) {
        results.push(subArray);
    });

    return results;
};



function tryFun() {
    var movieLists = [
        {
            name: "New Releases",
            videos: [
                {
                    "id": 70111470,
                    "title": "Die Hard",
                    "boxart": "http://cdn-0.nflximg.com/images/2891/DieHard.jpg",
                    "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 4.0,
                    "bookmark": []
                },
                {
                    "id": 654356453,
                    "title": "Bad Boys",
                    "boxart": "http://cdn-0.nflximg.com/images/2891/BadBoys.jpg",
                    "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 5.0,
                    "bookmark": [{ id: 432534, time: 65876586 }]
                }
            ]
        },
        {
            name: "Dramas",
            videos: [
                {
                    "id": 65432445,
                    "title": "The Chamber",
                    "boxart": "http://cdn-0.nflximg.com/images/2891/TheChamber.jpg",
                    "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 4.0,
                    "bookmark": []
                },
                {
                    "id": 675465,
                    "title": "Fracture",
                    "boxart": "http://cdn-0.nflximg.com/images/2891/Fracture.jpg",
                    "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 5.0,
                    "bookmark": [{ id: 432534, time: 65876586 }]
                }
            ]
        }
    ];

return movieLists.map(movieList=>
        movieList.videos.map(video=>video.id))
.concatAll();
}

Похоже, мне здесь не хватает какой-то хитрости. Спасибо, что заглянули в это. Не должен ли Javascript добавить функцию в ее прототип, который определен в начале файла?

Ответы [ 3 ]

0 голосов
/ 05 мая 2018

Вы звоните tryFun до добавления concatAll. Добавьте метод к прототипу перед вызовом tryFun:

Array.prototype.concatAll = function() {
    var results = [];
    this.forEach(function(subArray) {
        results.push(subArray);
    });

    return results;
};

console.log(tryFun());


function tryFun() {
    var movieLists = [
        {
            name: "New Releases",
            videos: [
                {
                    "id": 70111470,
                    "title": "Die Hard",
                    "boxart": "http://cdn-0.nflximg.com/images/2891/DieHard.jpg",
                    "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 4.0,
                    "bookmark": []
                },
                {
                    "id": 654356453,
                    "title": "Bad Boys",
                    "boxart": "http://cdn-0.nflximg.com/images/2891/BadBoys.jpg",
                    "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 5.0,
                    "bookmark": [{ id: 432534, time: 65876586 }]
                }
            ]
        },
        {
            name: "Dramas",
            videos: [
                {
                    "id": 65432445,
                    "title": "The Chamber",
                    "boxart": "http://cdn-0.nflximg.com/images/2891/TheChamber.jpg",
                    "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 4.0,
                    "bookmark": []
                },
                {
                    "id": 675465,
                    "title": "Fracture",
                    "boxart": "http://cdn-0.nflximg.com/images/2891/Fracture.jpg",
                    "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 5.0,
                    "bookmark": [{ id: 432534, time: 65876586 }]
                }
            ]
        }
    ];

return movieLists.map(movieList=>
        movieList.videos.map(video=>video.id))
.concatAll();
}

Но мутирование встроенных объектов - это очень плохая практика - было бы лучше вызвать отдельную функцию или использовать свою собственную оболочку.

0 голосов
/ 05 мая 2018

Как правило, в связи с тем, что вы пытаетесь реализовать, вы можете довольно легко обойтись без функции .concatAll(), поскольку .concat() является переменным и автоматически выравнивает массивы.

Таким образом, с помощью "расширенного синтаксиса" вы можете сделать это:

return [].concat(...movieLists.map(
    movieList => movieList.videos.map(video => video.id))
);

Вот живая демонстрация:

console.log(tryFun());

function tryFun() {
  var movieLists = [{
      name: "New Releases",
      videos: [{
          "id": 70111470,
          "title": "Die Hard",
          "boxart": "http://cdn-0.nflximg.com/images/2891/DieHard.jpg",
          "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
          "rating": 4.0,
          "bookmark": []
        },
        {
          "id": 654356453,
          "title": "Bad Boys",
          "boxart": "http://cdn-0.nflximg.com/images/2891/BadBoys.jpg",
          "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
          "rating": 5.0,
          "bookmark": [{
            id: 432534,
            time: 65876586
          }]
        }
      ]
    },
    {
      name: "Dramas",
      videos: [{
          "id": 65432445,
          "title": "The Chamber",
          "boxart": "http://cdn-0.nflximg.com/images/2891/TheChamber.jpg",
          "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
          "rating": 4.0,
          "bookmark": []
        },
        {
          "id": 675465,
          "title": "Fracture",
          "boxart": "http://cdn-0.nflximg.com/images/2891/Fracture.jpg",
          "uri": "http://api.netflix.com/catalog/titles/movies/70111470",
          "rating": 5.0,
          "bookmark": [{
            id: 432534,
            time: 65876586
          }]
        }
      ]
    }
  ];

  return [].concat(...movieLists.map(
      movieList => movieList.videos.map(video => video.id))
  );
}

Или вы можете использовать .reduce() и поставить .concat() в обратном вызове.

  return movieLists.reduce(
      (res, movieList) => res.concat(...movieList.videos.map(video => video.id))
  , []);
0 голосов
/ 05 мая 2018

Ооо понял! Его программный поток concatAll никогда не добавлялся. Просто перемещение вызова помогает:

Array.prototype.concatAll = function() {
    var results = [];
    this.forEach(function(subArray) {
        results.push(subArray);
    });

    return results;
};

console.log(tryFun());
...