Пробежать по элементам массива, выбрать из него некоторые элементы или сформировать новый массив необходимо довольно часто. Это можно сделать классическим способом:
Однако в 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) эти функции тоже поддержаны под другими именами и с разными вариациями.
