Пробежать по элементам массива, выбрать из него некоторые элементы или сформировать новый массив необходимо довольно часто. Это можно сделать классическим способом:
Однако в ECMA-262 [1] и большинстве фрэймворков поддержаны альтернативные (более элегантные) способы для достижения этой цели:
Вы вызываете методы массива передавая им функцию (closure, замыкание, lambda) которая будет вызвана для каждого элемента массива с параметрами (element /* элемент массива*/, index /* индекс этого элемента*/, array /*сам массив*/). В случае функций map и filter создаются новые массивы, которые будут заполнены тем, что возвращает функция (в случае map) или теми элементами над которыми функция вернула true (в случае filter).
Вторым параметром в эти функции можно передать thisObject объект который будет скрыватся за this внутри функции при ее выполнении) [1]:
В случае если браузер не поддерживает эти функции их можно определить самомтоятельно [2]:
Среди фрэймворков самая граммотная поддержка этих функций сделана в dojo. Где названия функций совпадают со спецификацией и переопределяются если не поддержаны. В остальных (Ext, jquery, prototype) эти функции тоже поддержаны под другими именами и с разными вариациями.
var arr=[1,2,3,4,5,6,7] var map=[]; var subarray=[]; for(var i=0,len=arr.length;i<len;i++){ var item = arr[i]; //do something alert(item); //map and sub if(/*some condition*/){ map.push(item +1); subarray.push(item) } }
Однако в ECMA-262 [1] и большинстве фрэймворков поддержаны альтернативные (более элегантные) способы для достижения этой цели:
var arr=[1,2,3,4,5,6,7] arr.forEach(function((element, index, array){ alert (element); }) var map= arr.map(function((element, index, array){ if(/*some condition*/) return element; }) var subarray=arr.filter(function((element, index, array){ return /*some condition*/})
Вы вызываете методы массива передавая им функцию (closure, замыкание, lambda) которая будет вызвана для каждого элемента массива с параметрами (element /* элемент массива*/, index /* индекс этого элемента*/, array /*сам массив*/). В случае функций map и filter создаются новые массивы, которые будут заполнены тем, что возвращает функция (в случае map) или теми элементами над которыми функция вернула true (в случае filter).
Вторым параметром в эти функции можно передать thisObject объект который будет скрыватся за this внутри функции при ее выполнении) [1]:
var writer = { sb:[], write: function (s) { this.sb.push(s); }, writeln: function (s) { this.write(s + "\n"); }, toString: function () { return this.sb.join(""); } }; [2, 5, 9].forEach(writer.writeln, writer); print(writer.toString()); // assumes print is already defined
В случае если браузер не поддерживает эти функции их можно определить самомтоятельно [2]:
if (!Array.prototype.forEach) { Array.prototype.forEach = function(fun /*, thisp*/) { var len = this.length; if (typeof fun != "function") throw new TypeError(); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) fun.call(thisp, this[i], i, this); } }; } if (!Array.prototype.filter) { Array.prototype.filter = function(fun /*, thisp*/) { var len = this.length; if (typeof fun != "function") throw new TypeError(); var res = new Array(); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) { var val = this[i]; // in case fun mutates this if (fun.call(thisp, val, i, this)) res.push(val); } } return res; }; } if (!Array.prototype.map) { Array.prototype.map = function(fun /*, thisp*/) { var len = this.length; if (typeof fun != "function") throw new TypeError(); var res = new Array(len); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) res[i] = fun.call(thisp, this[i], i, this); } return res; }; }
Среди фрэймворков самая граммотная поддержка этих функций сделана в dojo. Где названия функций совпадают со спецификацией и переопределяются если не поддержаны. В остальных (Ext, jquery, prototype) эти функции тоже поддержаны под другими именами и с разными вариациями.