• In handling of optional parameter in constructor I got a bit lost... and still am... ?-(

    This is the original code, and I do not know what is wrong with it...

    // goal: pass an optional C(onfig) object to update the C(onfig) in prototype
    
    function Clazz(C) {
      if (C) for (var v in C) this.C[v] = C[v];
    }
    
    Clazz.prototype.C = 
    { c: 100
    };
    
    var aClazz  = new Clazz();
    console.log("aClazz.C.C =",aClazz.C.C);
    

    Running this code I get following console output:

     1v70 Copyright 2014 G.Williams
    >echo(0);
    aClazz.C.C = 100
    =undefined
    Uncaught Error: FOR loop can only iterate over Arrays, Strings or Objects, not undefined
     at line 2 col 43
      if (C) for (var v in C) this.C[v] = C[v];
                                               ^
    > 
    

    I had expected that by design the if would have taken care of an undefined parameter variable C and skip the for-loop. The for-loop should only execute when is C defined.

    Invoking constructor with empty object works:

    var aClazz  = new Clazz({});
    

    logs:

     1v70 Copyright 2014 G.Williams
    >echo(0);
    aClazz.C.C = 100
    =undefined
    >
    

    Invoking constructor with changing object works:

    var aClazz  = new Clazz({ C:50 });
    

    logs:

     1v70 Copyright 2014 G.Williams
    >echo(0);
    aClazz.C.C = 50
    =undefined
    >
    

    Next step I tried was for loop with curly braces - to no avail:

      if (C) for (var v in C) { this.C[v] = C[v]; }
    

    Next step I tried if with curly braces - but not the for loop - and it worked... (update: ...hold your horses, this was not the last snag... keep on reading!)

      if (C) { for (var v in C) this.C[v] = C[v]; }
    

    Sure, I always recommend to use curly braces. Before I though added them, I tried the avenue of try-catch to find out what is going on. It seemed to me odd that the reporting of the error was actually after execution of all the code and the error did not stop the code from executing... (as it would have done in a browser).

    function Clazz(C) {
        if (C) for (var v in C) this.C[v] = C[v];
    }
    
    Clazz.prototype.C = 
    { C: 100 };
    
    try {
      var aClazz  = new Clazz();
      console.log("Clazz() constructor passed");
    } catch(x) {
      console.log("exception in Clazz() constructor:",x);
    }
    console.log("aClazz.C.C =",aClazz.C.C);
    

    logs:

     1v70 Copyright 2014 G.Williams
    >echo(0);
    Clazz() constructor passed
    aClazz.C.C = 100
    =undefined
    Uncaught Error: FOR loop can only iterate over Arrays, Strings or Objects, not undefined
     at line 2 col 45
        if (C) for (var v in C) this.C[v] = C[v];
                                                 ^
    > 
    

    Surprisingly, the try-catch does not catch the error... it lets the faulty expression to pass... so I wrapped the actually expression in the constructor into a try-catch block...

    function Clazz(C) { // --------------------------
      try {
        if (C) for (var v in C) this.C[v] = C[v];
        console.log("Clazz() constructor passed");
      } catch(x) {
        console.log("exception in Clazz() constructor:",x);
      }
    }
    
    Clazz.prototype.C = 
    { C: 100 };
    
    var aClazz  = new Clazz();
    console.log("aClazz.C.C =",aClazz.C.C);
    

    with the same puzzling result...

    So I'm asking:

    • What is going on here?
    • Why is the if not catching when not provided with curly braces?
    • Why it the try-catch not catching the error
    • Why is the error reported at the end of all reporting... (console output)

    I had tried to use try-catch block in a different project,... and it did not work there either. Because int that project it was precaution and the anticipated possible error did not show (yet), so I ignored 'to go to the bottom of it'.

About

Avatar for allObjects @allObjects started