1

A lot of people where confused by my last question. I hope I can clear things up with this one. HERE is what I need to do:

var arr = ["Init Value", "Does Not", "Matter"];
arr.onGet = updater;   // Register arr with updater function
alert(arr[0]);  // should return 1;
alert(arr[0]);  // should return 2;
alert(arr[0]);  // should return 3;
alert(arr[0]);  // should return 4;
alert(arr[0]);  // should return 5;

var counter = 0;
function updater(){
  counter = counter + 1;
  return counter;
}

See what I did there? Init value does not matter, it's the updater function that is pulling the values.

Now this does not work of course, since arr does not automatically call the function updater and there is no event onGet. Some people might say, well that's just crazy talk, how can you run a function when it's not even called. That is true, but a VARIABLE is called (in our case arr[0], so can't you just bind(link) it up to another function when arr[0] is called? In essence, this is an auto-updater, hence my question.

Also, I have given up trying to work this in IE7, how about just Google Chrome?


Solution by Skyd:

function onGet(obj) {
    var index = 0;
    var counter = 0;
    for (var prop in obj) {
        (function(thisIndex, thisProp) {
            obj.__defineGetter__(thisIndex, function() {
                counter = counter + 1;
                return counter ; 
            });
        })(index, prop)
        index++;
    };
    obj.__defineGetter__("length", function() {
        return 1000;
    });
    return obj;
}

var myObj = [100,200,300];

onGet(myObj);

alert(myObj[1]);     // 1
alert(myObj[2]);     // 2
alert(myObj[3]);     // 3
alert(myObj.length); // 1000 <-- Arbitary value which you can change
Bill Software Engineer
  • 7,362
  • 23
  • 91
  • 174
  • I wonder what this is used for really – Ibu Dec 15 '11 at 01:43
  • If you really want to know, I am creating arbitrary array which does not exist except in concept only. Like arbitrary numbers - useful, but not real in any physical sense. – Bill Software Engineer Dec 15 '11 at 01:45
  • possible duplicate of [Use JS function as a ARRAY OBJECT](http://stackoverflow.com/questions/8512405/use-js-function-as-a-array-object) – Naftali Dec 15 '11 at 03:07

1 Answers1

3

You should look into javascript Setters and Getters, which lets you run functions when a certain property is being accessed or modified. It works great on objects. For arrays, its a little harder, since arrays can potentially have infinite properties (where properties are its indicies). If you have a fixed size array though, then something like this might work:

var arr = ["Fixed", "Array", "Size", "Will", "Not", "Ever", "Change"];
for (var i=0; i<arr.length; i++){
    debug(i);
    (function(index){
         arr.__defineGetter__(index, function(){return updater();});        
    })(i);
}
alert(arr[0]) // will return results of updater() call;

It may be better to use a custom object with a getter/setter rather than using a fixed size array.

Also, look at these links: Getter/setter on javascript array? and http://javascriptweblog.wordpress.com/2010/11/15/extending-objects-with-javascript-getters/

Community
  • 1
  • 1
Skyd
  • 411
  • 4
  • 11