При разработке фреймворка для XUL-UI (для Firefox плагинов) - встал вопрос о том, чтобы представлять элемент(там это чекбокс, селект, групбокс например) и группу тех-же элементов (массив тобишь) одним и тем же интерфейсом. При том что все элементы хоть и наследуются от от одного базового, но имеют разные прототипы(классы). То есть должны работать простые примеры:
element.attr('class','some');//устанавливает класс одного элемента в some
[element1, element2, element3].attr('class','some');//устанавливает класс 3-х элементов в some
//метода val - например нет в базовом классе этого фреймворка, потому что не все имеют значения - логично вроде
element.val();//возвращает значение элемента
[element1, element2, element3].val();//возвращает массив, каждый элемент которого соответствует значению каждого элемента в исходном массиве
[element1, element2].find('.some').attr('atr','atrVal');//в 2-х элементах находим все дочерние элементы с классом some и присваиваем им некий аттрибут
Заворачивать в один класс работу как со множеством, так и с одним элементов( как делает jQuery) - было бы накладно по архитектуре, и грозило бы потерей гибкости. Но оставлять как в mootools - аля забудь про множества, тоже неприемлемо. Очень быстро нагуглилось классное решение вопроса - Proxy
https://developer.mozilla.org/en-US/..._Objects/Proxy . Создал обёрточный метод который при попытке вызова любого метода множества - вызывает его у каждого элемента множества, и формирует резутат-массив, каждый элемент которого соответствует результату вызванного множества:
//функция-проксер, проксирующая массив
var Multiplicity = function(in_array){
var proxy = new Proxy(in_array,{
get: function(target, name) {
if (name in target) return target[name];
var proxyMethod = function(){
var proxyResult = [];
for(var i=0;i<target.length;i++){
if (!target[i]) continue;
if (typeof target[i][name] == 'function'){
proxyResult.push(target[i][name].apply(target[i], arguments));
}else if (typeof target[i][name] != 'undefined'){
proxyResult.push(target[i][name]);
}else{
proxyResult.push(undefined);
}
}
return Multiplicity(proxyResult);
}
return proxyMethod;
}
});
return proxy;
};
//ПРИМЕР использования проксера массивов
var cls = function(){
this.f = function(){return new subCls();};
};
var subCls = function(){
this.f2 = function(){return Math.random();};
};
Multiplicity([new cls(), new cls()]).f().f2();//выведет массив из двух случайных чисел
Multiplicity([new cls(), new subCls()]).f2();//выведет [undefined, случайное_число]
подход нравится своей волшебной гибкостью(с первого взгляда) - какие бы программисты не дописали методы в классы элементов, Proxy будет их "есть". Но вот вопрос, нет ли в таком подходе подводных камней, да таких что могут потопить UI-фреймворк? Есть ли причины не использовать Proxy кроме того что объект пока по-умолчанию доступен только в Firefox (а в остальных браузерах пока в стадии experimental)?