1

I'm working on a hunk of software for an internship and I've been tasked to add functionality to a system that builds a table of Award Levels based on existing Prizes and numbers of Cards.

I'm getting into the function for adding rows and I find an extremely strange pair of declarations. I'm going to post the function itself lest lack of context inhibit answers. I've searched for various combinations of "cast","array" and "number" but nothing seemed to be related to this practice.

this.addNewTableRow = function(){
    var request = new XMLHttpRequest();
    awardLevel = this.length + 1;
    request.onreadystatechange = function(){
        if (request.readyState == 4 && request.status == 200){
            if(request.responseText != -1){
                var tableBody = document.getElementById('award-body');
                var sqlId = parseInt(JSON.parse(request.responseText));

                var prevSelector = document.getElementById('level-select-'+self.length);
                var prevLevel = 0;
                if(prevSelector != null){
                    prevLevel = parseInt(prevSelector.value);
                }

                var minCardQuantity = prevLevel + 1;
                var maxCardQuantity = minCardQuantity + 100;

                var awardLevel = {
                    id: sqlId,
                    awardId: 0,
                    certificateId: 0,
                    awardLvl: self.length + 1,
                    cardQuantity: minCardQuantity
                };

                self.changeLevelSelect(self.length + 1, minCardQuantity);

                var row = self.getRow(awardLevel, minCardQuantity, maxCardQuantity);

                tableBody.appendChild(row);
                self.awards[length] = awardLevel;
                self.length++;
            }
        }
    }
    request.open('GET', '_insert_award_lvl.php?level=' + awardLevel, true);
    request.send();
    location.reload();  
}

The behavior that has me puzzled is the treatment of AwardLevel

It's modified before it is declared, which even with a vague understanding of hoisting I don't think should work. Further the early assignment operator appears to be assigning the variable to an Int whereas it is assigned and used as an associative array later on.

The overall code has a lot of unexpected and confusing behavior and I'm already inexperienced with Javascript.

4
  • 1
    This is a very bad code, with two different awardLevel variables, one being global (it's missing the var declaration). Commented Jul 1, 2014 at 14:33
  • The awardLevel inside the inner closure shadows the outer declaration which either is declared inside the surrounding constructor code or implicitly global. Commented Jul 1, 2014 at 14:35
  • JavaScript doesn't have associative arrays as such; what resembles associative arrays in other languages is an object in JS. Commented Jul 1, 2014 at 14:37
  • I see, well it's being treated like an associative array, so I asked the question like that to try and get the right kind of help. While it technically is an object searching for Javascript Associative Arrays found me a lot of syntax help. Commented Jul 1, 2014 at 14:40

1 Answer 1

1

The external awardLevel variable isn't "modified before it is declared" : it's never declared. The other declaration is only valid for the function in which it is declared (and it shadows the external one).

This means :

  • you have two different variables with same name and different semantics (one is an integer, one is an object)
  • one of them is never declared (it's global) and is shadowed in the internal scope by the declared one
  • the fact awardLevel has a property named awardLvl doesn't make it better
  • this is a bad careless code

A way to make all this slightly less confusing would be this :

// awardLevel = this.length + 1; remove that line
request.onreadystatechange = function(){
    // don't change which is here
}
request.open('GET', '_insert_award_lvl.php?level=' + (this.length + 1), true);
Sign up to request clarification or add additional context in comments.

3 Comments

"it's never declared" -- at least not in the posted code, which clearly is a fragment from a constructor or similar function. It quite easily could be declared elsewhere and not necessarily global.
Yeah thats the thing, theres no other declaration for the variable by that name, and none is passed in from other code. Can the empty assignment of the external variable be considered a declaration without "var"? I've searched every document that interacts with this one and that variable is not being passed in.
By the way thanks for the explanations, if I was in a language I was more familiar with(Java, C++) I'd have probably guessed the same thing, but Javascript never seems to enforce rules like I'd expect. Further complication, I've actually used the attributes of the awardLevel object within the _insert_award_lvl.php file, which completely blows my mind. I know its not great, I've been told the guy who wrote it was even greener than I am when he got to it.

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.