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
3
  • I wonder what this is used for really Commented Dec 15, 2011 at 1: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. Commented Dec 15, 2011 at 1:45
  • possible duplicate of Use JS function as a ARRAY OBJECT Commented Dec 15, 2011 at 3:07

1 Answer 1

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/

Sign up to request clarification or add additional context in comments.

3 Comments

Sorry this isn't quite right. Am editing my answer, please hold.
Skyd, you are awesome and it works! Thanks a lot! Actually I pretty much got it to work, I'll post the code in OP in one sec.
if you want to take credit to my original question, please post your solution over at stackoverflow.com/questions/8512405

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.