Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript reference in loop: "Uncaught TypeError: Cannot read property 'value' of undefined"

I tried debugging my code for like a few hour but I got nothing out of it. The issue is that it makes absolutely no sense on why it reports an error every time I tried to use document.forms[0][i] (i as the iterator) in the event listener but "this" satisfies the code.

//broken
var addListeners = function() {
    var i;
    var formFields = document.forms[0];
    var formSubmit = formFields["submit"];

    for (i = 0; i < formFields.length; i++) {
        if (formFields[i] != formSubmit) {
            formFields[i].onblur = (function () {
                checkNonEmpty(formFields[i]);
            });
        }
    }
};

//works
var addListeners = function() {
    var i;
    var formFields = document.forms[0];
    var formSubmit = formFields["submit"];

    for (i = 0; i < formFields.length; i++) {
        if (formFields[i] != formSubmit) {
            formFields[i].onblur = (function () {
                checkNonEmpty(this);
            });
        }
    }
};

Wouldn't "this" refer to document.forms[0][i]?... formFields references to document.forms[0]. However the exact same code (with "this" where formFields[i] is at) works just fine.

Here is the demo: http://jsfiddle.net/PbHwy/

like image 437
W3Geek Avatar asked Jul 04 '26 04:07

W3Geek


1 Answers

Cranio's answer already contains the root of the matter. To get rid of this you can either include formFields[i] by using closures

var blurCallbackGenerator = function(element){
    return function () {
        checkNonEmpty(element);
    };
};
formFields[i].onblur = blurCallbackGenerator(formFields[i]);

/* // dense version:
formFields[i].onblur = (function(element){
    return function () {
        checkNonEmpty(element);
    };
})(formFields[i]);
*/

or simply using this.

See also:

  • MDN: Creating closures in loops: A common mistake
like image 86
Zeta Avatar answered Jul 08 '26 06:07

Zeta



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!