Я уже давно желаю, чтобы линия между естественными массивами и обычными объектами была полностью размыта, не только расширяя объект с теми же возможностями, что и массивы, полученные в ES5, но собираются вместе с мой собственный пакет методов с обеих сторон.Проблемы с расширением регулярных объектов для поддержки возможностей массива ES5
Пара умных людей думала об этих изменениях парадигмы. Как Ангус Кролл упомянул в статье javascript-object-keys-finally:
«Кроме того, как линия между массивами и обычными объектами размывают (автоматизированный заказных добытчиков и сеттера) мы, вероятно, увидеть рост общего «array- как «объекты, которые пользуются лучшими из обоих миров - неточечные идентификаторы и доступ к набору богатых API, определенному Array.prototype. EcmaScript 5, по-видимому, предвосхитил эту тенденцию, введя общий метод , определенный одним типом но может использоваться любым ».
По пути, он получить вещи кодируются в статье: extending-objects-with-javascript-getters
function extendAsArray(obj) {
if (obj.length === undefined || obj.__lookupGetter__('length')) {
var index = 0;
for (var prop in obj) {
if(!obj.__lookupGetter__(prop)) {
(function(thisIndex, thisProp) {
obj.__defineGetter__(thisIndex, function() {return obj[thisProp]});
})(index, prop)
index++;
}
};
obj.__defineGetter__("length", function() {return index});
}
return obj;
}
var myObj = {
left:50,
top:20,
width:10,
height:10
}
extendAsArray(myObj);
[].map.call(myObj,function(s){return s+' px'}).join(', ');
//"50px ,20px ,10px, 10px"
Этот подход является исключительно интересным для меня. Тем не менее, это также, по-видимому, страдает от пары серьезных проблем!
Как насчет расширения оригинальной модели myObj с парой новых свойств? Должны ли мы запускать
extendAsArray
на каждое изменение недвижимости для его обновления относительноlength
property?Когда недвижимость меняется, это относится не только к соответствующему свойству
length
; индексы массива также должны обновляться, так как запрос свойства массива определенно оказывается неопределенным. Поэтому, когдаconsole.log(myObj.length) -> 4 myObj.zAxis=0
затем
console.log(myObj[4]) // -> undefined! console.log(myObj.length) // -> 4!
Я изменил код Ангуса соответственно, поэтому он поддерживает автоматическое обновление length
недвижимости по запросу:
function extendAsArray(obj) {
var index = 0;
for(var prop in obj){
if(!obj.__lookupGetter__(prop)){
(function(thisIndex, thisProp){
Object.defineProperty(obj, thisIndex, {
get: function(){return obj[thisProp]}
, enumerable: true
, configurable: true
, writeable: true
});
})(index, prop)
index++;
}
}
if(!obj.__lookupGetter__('length')){
Object.defineProperty(obj, 'length', {
get: function(){
return extendAsArray(obj);
}
, configurable: true
, writeable: true
});
return obj;
}
else{
return index;
}
}
Проблема заключается в том: как мы обновляем индексы массива объекта вместе с его length
prop erty, когда свойство изменено, добавлено или удалено?
Должен ли я использовать Object.watch
?
И все еще остается нерешенный вопрос: как вмешиваться в мою собственную библиотеку утилиты unshimmed, сделав ее также для объектов согласованным образом?
Я использую ту же кодовую для обоих типов: z.Object({}).mapEvery
делает то же самое, как z.Object([]).mapEvery
Пожалуйста, не упоминая JQuery и Подчеркиваем, а также. У меня есть всеобъемлющий, настраиваемый список методов для обоих типов, и я готов использовать стандарты, которые могут быть завершены, возможно, с моими несмеженными, и я не хочу реорганизовать его!
Разница между объектами и массивами больше, чем свойство длины массива. Насколько я знаю :-) есть несколько ES5 перечисляемых методов, таких как карта, фильтр добавляется в последние браузеры, однако IE9 также поддерживает его. Эти методы полностью недоступны для родных объектов. –
Вот он: https://github.com/zludany/enumerable.js –
Оба [* map *] (http://www.ecma-international.org/ecma-262/5.1/#sec-15.4. 4.19) и [* filter *] (http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.20) указаны в ES5, они оба «намеренно генерические» не требуют от [их] это значение - объект Array », поэтому они будут работать с любым родным объектом с подходящими свойствами. Они не обязаны работать с объектами хоста (но для объектов DOM во многих браузерах). – RobG