themightylc
themightylc

Reputation: 324

javascript throws Uncaught TypeError: Cannot set property '0' of undefined when filling multidimensional array

I am debugging a 5-odd-year old script and this is driving me nuts. None of the answers I found could help me pinpoint the error. I have made a new Version after reading up on Arrays. Neither the position nor the "timing" of the Exception makes any sense to me whatsoever...

//NEW VERSION
tasks=[];
status=[];

function initCalendarInfo(){
    for (k=0;k<40;k++) {
        tasks[k] = [];
        status[k] = [];
        for (i=0;i<12;i++) {
            tasks[k][i]= [];
            //THROWS EXCEPTION IN NEXT LINE k=0,i=0,j=0
            status[k][i]= [];
            for (j=0;j<31;j++){
                tasks[k][i][j]='';
                status[k][i][j]=0;
            }
        }
    }
}

//OLD VERSION
tasks = new Array(40);
status= new Array(40);

function initCalendarInfo(){
    for (k=0;k<40;k++) {
        tasks[k] = new Array(12);
        status[k] = new Array(12);
        for (i=0;i<12;i++) {
            tasks[k][i]= new Array(31);
            status[k][i]= new Array(31);
            for (j=0;j<31;j++){
                tasks[k][i][j]='';
                //THROWS EXCEPTION IN NEXT LINE k=0,i=1,j=0 
                status[k][i][j]=0;
            }
        }
    }
}   

Upvotes: 2

Views: 628

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074248

This is one of the many reasons to avoid global variables.

On browsers, there's already a global variable called status and you can't change its type. It's a string, and assigning an array to it just causes the array to be coerced to string (a blank array coerces to an empty string). Back in the day, status was used for setting the text in the browser's status bar. Browsers mostly A) Don't have permanent status bars anymore (just ones that appear as overlays), and B) Don't let you change them when they do (as people used to show a fake version of a link when the real link did...well...other things).

If you put your entire script in a scoping function and declare your variables, the problem goes away:

(function () {
    //NEW VERSION
    var tasks = [];
    var status = [];

    function initCalendarInfo() {
        for (var k = 0; k < 40; k++) {
            tasks[k] = [];
            status[k] = [];
            for (var i = 0; i < 12; i++) {
                tasks[k][i] = [];
                //THROWS EXCEPTION IN NEXT LINE k=0,i=0,j=0
                status[k][i] = [];
                for (var j = 0; j < 31; j++) {
                    tasks[k][i][j] = '';
                    status[k][i][j] = 0;
                }
            }
        }
    }

    initCalendarInfo();
    snippet.log(JSON.stringify(status, null, 2));
    snippet.log(JSON.stringify(tasks, null, 2));
})();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Regarding declaring variables: Your code as is, even if you put it in a scoping function, falls prey to The Horror of Implicit Globals. It's important to declare your variables.

Upvotes: 3

themightylc
themightylc

Reputation: 324

Nevermind good people. "status" seems to be a reserved word or refer to the status bar or something. Just renamed the variable and voila. The behaviour is strange, anyways - especially with the pre-defined Arrays so any light shed on this will still be appreciated!

Upvotes: 0

Related Questions