Programming in javascript: Problems with extending ES5 Array capabilities to regular Objects on newest questions tagged javascript – Stack Overflow

I have long ago been willing to get the line between native Arrays and regular Objects totally blurred, not only extending Object with the same capabilities as Arrays got in ES5, but bundle up my custom packages of methods on both sides.

Couple of smart people thought about these paradigm changes. Like Angus Croll mentioned it in the article javascript-object-keys-finally:

“Moreover as the line between Arrays and regular Objects blurs (aided
by custom getters and setters) we’re likely to see a growth in generic
“array-like” objects which enjoy the best of both worlds – non-numeric
identifiers and access to the rich API set defined by Array.prototype.
EcmaScript 5 has apparently pre-empted this trend by introducing the
generic method, defined by one type but useable by any.”

Along the way, he get things coded in the article:
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"

This approach is exceptionally interesting for me. However, it is also seemingly suffering a couple of serious problems!

  1. How about extending the original myObj model with a couple of new properties?
    Should we run extendAsArray on every property change to update it’s concerning length property?

  2. When a property changes, it’s not just the length property that’s relevant; the array indices should also be updated, because an array-like property request definitely turns out to be undefined. So when

    console.log(myObj.length) -> 4
    myObj.zAxis=0
    

    then

    console.log(myObj[4]) // -> undefined!
    console.log(myObj.length) // -> 4!
    

I have modified Angus’ code accordingly, so it supports automatic update of length property on request:

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')){
       //alert('lokup: '+obj.__lookupGetter__('length'));
       Object.defineProperty(obj, 'length', {
          get: function(){
            return zextendAsArray(obj);
          }
          , configurable: true
          , writeable: true
       });
       return obj;
    }
    else{
       return index;
    }
}

The problem is: how do we updating the object’s array indices together with its length property when a property is changed, added or removed?

Should I use Object.watch?

And there is still an unsolved question: how to interfere with my own unshimmed utility library, having made it also for Objects in a consistent way?

I am using the same codebase for both types: z.Object({}).mapEvery does the same as z.Object([]).mapEvery

Please avoid mentioning JQuery, and Underscore as well. I have got a comprehensive, custom list of methods for both types, and I am willing to use the standards completed possibly with my unshimmed ones, and I am not willing to refactor it!

See Answers


source: http://stackoverflow.com/questions/15373344/problems-with-extending-es5-array-capabilities-to-regular-objects
Programming in javascript: programming-in-javascript



online applications demo