Array.prototype.filter()

Метод filter() создаёт новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции.

Синтаксис

arr.filter(callback[, thisArg])

Параметры

callback
Функция проверки каждого элемента. Вызывается с аргументами (element, index, array). Возвращает true для сохранения элемента и false для его пропуска.
thisArg
Необязательный параметр. Значение, используемое в качестве this при выполнении функции callback.

Описание

Метод filter() вызывает переданную функцию callback один раз для каждого элемента, присутствующего в массиве, и конструирует новый массив со всеми значениями, для которых функция callback вернула true или значение, становящееся true при приведении в boolean. Функция callback вызывается только для индексов массива, имеющих присвоенные значения; она не вызывается для индексов, которые были удалены или которым значения никогда не присваивались. Элементы массива, не прошедшие проверку функцией callback, просто пропускаются и не включаются в новый массив.

Функция callback вызывается с тремя аргументами:

  1. значение элемента;
  2. индекс элемента;
  3. массив, по которому осуществляется проход.

Если в метод filter() был передан параметр thisArg, при вызове callback он будет использоваться в качестве значения this. В противном случае, в качестве значения this будет использоваться значение undefined. В конечном итоге, значение this, наблюдаемое из функции callback, определяется согласно обычным правилам определения this, видимого из функции.

Метод filter() не изменяет массив, для которого он был вызван.

Диапазон элементов, обрабатываемых методом filter(), устанавливается до первого вызова функции callback. Элементы, добавленные в массив после начала выполнения метода filter(), не будут посещены функцией callback. Если существующие элементы массива изменятся, значения, переданные в функцию callback, будут значениями на тот момент времени когда метод filter() посетит их; удалённые элементы посещены не будут.

Примеры

Пример: отфильтровывание всех маленьких значений

Следующий пример использует filter() для создания отфильтрованного массива, все элементы которого больше или равны 10, а все меньшие 10 удалены.

function isBigEnough(value) {
  return value >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// массив filtered равен [12, 130, 44]

Пример: фильтрация неверных записей в JSON

В следующем примере метод filter() используется для создания отфильтрованного объекта JSON, все элементы которого содержат ненулевое числовое поле id.

var arr = [
  { id: 15 },
  { id: -1 },
  { id: 0 },
  { id: 3 },
  { id: 12.2 },
  { },
  { id: null },
  { id: NaN },
  { id: 'undefined' }
];

var invalidEntries = 0;

function filterByID(obj) {
  if ('id' in obj && typeof(obj.id) === 'number' && !isNaN(obj.id)) {
    return true;
  } else {
    invalidEntries++;
    return false;
  }
}

var arrByID = arr.filter(filterByID);
console.log('Отфильтрованный массив\n', arrByID); // [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
// [{ id: 15 }, { id: -1 }, { id: 0 }, { id: 3 }, { id: 12.2 }]

console.log('Количество ошибочных записей = ', invalidEntries); // 4
// 4

Полифилл

Метод filter() был добавлен к стандарту ECMA-262 в 5-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать filter() в реализациях, которые не поддерживают этот метод. Этот алгоритм является точно тем, что описан в ECMA-262 5-го издания; он предполагает, что fn.call вычисляется в оригинальное значение Function.prototype.call() и что Array.prototype.push() содержит своё оригинальное значение.

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun/*, thisArg*/) {
    'use strict';

    if (this === void 0 || this === null) {
      throw new TypeError();
    }

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== 'function') {
      throw new TypeError();
    }

    var res = [];
    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++) {
      if (i in t) {
        var val = t[i];

        // ПРИМЕЧАНИЕ: Технически, здесь должен быть Object.defineProperty на
        //             следующий индекс, поскольку push может зависеть от
        //             свойств на Object.prototype и Array.prototype.
        //             Но этот метод новый и коллизии должны быть редкими,
        //             так что используем более совместимую альтернативу.
        if (fun.call(thisArg, val, i, t)) {
          res.push(val);
        }
      }
    }

    return res;
  };
}

Спецификации

Спецификация Статус Комментарии
ECMAScript 5.1 (ECMA-262)
Определение 'Array.prototype.filter' в этой спецификации.
Стандарт Изначальное определение. Реализована в JavaScript 1.6.
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'Array.prototype.filter' в этой спецификации.
Стандарт  
ECMAScript 2017 Draft (ECMA-262)
Определение 'Array.prototype.filter' в этой спецификации.
Черновик  

Совместимость с браузерами

Возможность Chrome Firefox (Gecko) Internet Explorer Opera Safari
Базовая поддержка (Да) 1.5 (1.8) 9 (Да) (Да)
Возможность Android Chrome для Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Базовая поддержка (Да) (Да) 1.0 (1.8) (Да) (Да) (Да)

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: Sinfiotli, burashka, Aleksej, Mingun
 Обновлялась последний раз: Sinfiotli,