Why doesn't JavaScript warn me when I use arr.lenght (misspelt) instead of arr.length in a loop? I also use...












61














I spent hours just to find out that I misspelt the word .length as .lenght. It can run normally with no warning at all. Why...?



I use 'use strict' and run on Node.js 10.13.0.



Code:






'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}












share|improve this question




















  • 6




    You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime. I'll suggest you to read stackoverflow.com/questions/1335851/….
    – mmontoya
    Dec 3 '18 at 3:13






  • 6




    Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
    – charlietfl
    Dec 3 '18 at 3:20








  • 48




    Because you aren't using TypeScript.
    – Ian Kemp
    Dec 3 '18 at 8:04






  • 6




    It also does not warn you about window.sdjkhednrgj for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
    – usr
    Dec 3 '18 at 11:38








  • 2




    If it would give a warning about these things, it would also give a warning every time you wrote if (someObject.someProperty==undefined) when the property was undefined...
    – Mr Lister
    Dec 3 '18 at 14:44
















61














I spent hours just to find out that I misspelt the word .length as .lenght. It can run normally with no warning at all. Why...?



I use 'use strict' and run on Node.js 10.13.0.



Code:






'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}












share|improve this question




















  • 6




    You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime. I'll suggest you to read stackoverflow.com/questions/1335851/….
    – mmontoya
    Dec 3 '18 at 3:13






  • 6




    Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
    – charlietfl
    Dec 3 '18 at 3:20








  • 48




    Because you aren't using TypeScript.
    – Ian Kemp
    Dec 3 '18 at 8:04






  • 6




    It also does not warn you about window.sdjkhednrgj for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
    – usr
    Dec 3 '18 at 11:38








  • 2




    If it would give a warning about these things, it would also give a warning every time you wrote if (someObject.someProperty==undefined) when the property was undefined...
    – Mr Lister
    Dec 3 '18 at 14:44














61












61








61


4





I spent hours just to find out that I misspelt the word .length as .lenght. It can run normally with no warning at all. Why...?



I use 'use strict' and run on Node.js 10.13.0.



Code:






'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}












share|improve this question















I spent hours just to find out that I misspelt the word .length as .lenght. It can run normally with no warning at all. Why...?



I use 'use strict' and run on Node.js 10.13.0.



Code:






'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}








'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}





'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}






javascript






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 6 '18 at 23:24









Peter Mortensen

13.5k1983111




13.5k1983111










asked Dec 3 '18 at 3:09









MangoLato

393210




393210








  • 6




    You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime. I'll suggest you to read stackoverflow.com/questions/1335851/….
    – mmontoya
    Dec 3 '18 at 3:13






  • 6




    Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
    – charlietfl
    Dec 3 '18 at 3:20








  • 48




    Because you aren't using TypeScript.
    – Ian Kemp
    Dec 3 '18 at 8:04






  • 6




    It also does not warn you about window.sdjkhednrgj for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
    – usr
    Dec 3 '18 at 11:38








  • 2




    If it would give a warning about these things, it would also give a warning every time you wrote if (someObject.someProperty==undefined) when the property was undefined...
    – Mr Lister
    Dec 3 '18 at 14:44














  • 6




    You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime. I'll suggest you to read stackoverflow.com/questions/1335851/….
    – mmontoya
    Dec 3 '18 at 3:13






  • 6




    Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
    – charlietfl
    Dec 3 '18 at 3:20








  • 48




    Because you aren't using TypeScript.
    – Ian Kemp
    Dec 3 '18 at 8:04






  • 6




    It also does not warn you about window.sdjkhednrgj for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
    – usr
    Dec 3 '18 at 11:38








  • 2




    If it would give a warning about these things, it would also give a warning every time you wrote if (someObject.someProperty==undefined) when the property was undefined...
    – Mr Lister
    Dec 3 '18 at 14:44








6




6




You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime. I'll suggest you to read stackoverflow.com/questions/1335851/….
– mmontoya
Dec 3 '18 at 3:13




You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime. I'll suggest you to read stackoverflow.com/questions/1335851/….
– mmontoya
Dec 3 '18 at 3:13




6




6




Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
– charlietfl
Dec 3 '18 at 3:20






Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
– charlietfl
Dec 3 '18 at 3:20






48




48




Because you aren't using TypeScript.
– Ian Kemp
Dec 3 '18 at 8:04




Because you aren't using TypeScript.
– Ian Kemp
Dec 3 '18 at 8:04




6




6




It also does not warn you about window.sdjkhednrgj for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
– usr
Dec 3 '18 at 11:38






It also does not warn you about window.sdjkhednrgj for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
– usr
Dec 3 '18 at 11:38






2




2




If it would give a warning about these things, it would also give a warning every time you wrote if (someObject.someProperty==undefined) when the property was undefined...
– Mr Lister
Dec 3 '18 at 14:44




If it would give a warning about these things, it would also give a warning every time you wrote if (someObject.someProperty==undefined) when the property was undefined...
– Mr Lister
Dec 3 '18 at 14:44












6 Answers
6






active

oldest

votes


















72














Because when you try to get a property that doesn't exist, it returns undefined, and 0 < undefined is false.






let arr = [1, 2, 3, 4];
console.log(arr.lenght) // undefined
console.log(arr.qwerty) // undefined
console.log(arr.lenght < 9999) // false
console.log(arr.lenght > 9999) // false

arr.length = 7 // <-- it's not a good idea
for(let i = 0; i < arr.length; i++) {console.log(arr[i])}





EDIT



I said 'javascript is not a strongly typed language' and it is true. But this way of adding new properties it is a feature of prototype-based programming, as @Voo said.



I also said .length=7 it's a bad idea. After reading a little more, in this case I still think it's a little weird to increase the length property after adding elements. Maybe it's fine to truncate, delete elements or empty an array, although in the latter case I would prefer arr= instead of arr.length=0.



There are some interesting examples about length property in the Mozilla documentation.




A JavaScript array's length property and numerical properties are
connected. Several of the built-in array methods (e.g., join(),
slice(), indexOf(), etc.) take into account the value of an array's
length property when they're called. Other methods (e.g., push(),
splice(), etc.) also result in updates to an array's length property.



var fruits = ;
fruits.push('banana', 'apple', 'peach');
console.log(fruits.length); // 3


When setting a property on a JavaScript array when the property is a
valid array index and that index is outside the current bounds of the
array, the engine will update the array's length property accordingly:



fruits[5] = 'mango';
console.log(fruits[5]); // 'mango'
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 6


Increasing the length.



fruits.length = 10;
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 10


Decreasing the length property does, however, delete elements.



fruits.length = 2;
console.log(Object.keys(fruits)); // ['0', '1']
console.log(fruits.length); // 2






share|improve this answer



















  • 4




    Setting the .length of an array is a very common idea and there's nothing wrong with it.
    – Bergi
    Dec 3 '18 at 8:27






  • 5




    PHP is also not a strongly typed language, yet it gives you a warning when you access a non-existing property. JavaScript, on the other hand, has no standard way to produce runtime warnings.
    – GOTO 0
    Dec 3 '18 at 8:37








  • 3




    @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
    – Bergi
    Dec 3 '18 at 10:33






  • 8




    @GOTO0 Yep, and you just summed up for me the irony in the way the dev world has been fawning over JavaScript for the last few years while at the same time pouring hate on PHP.
    – Spudley
    Dec 3 '18 at 13:22






  • 3




    Whether you get an error on accessing a non-existent property or not, has nothing to do if the language is strongly typed or not. This is more a feature of prototype based OOP languages.
    – Voo
    Dec 3 '18 at 14:18



















14














JavaScript arrays are treated as objects (though they are instances of Array). Hence, when you write arr.lenght, it treats lenght as a property of an object that is undefined. Hence, you don't get an error.



It simply tries to get a property that is undefined. Also, in your case, the loop just does not execute as the condition of the loop is never satisfied.






share|improve this answer































    8














    Why



    Standard JavaScript arrays aren't really arrays at all¹, they're objects, and if you read an object property that doesn't exist (like lenght), you get the value undefined (even in strict mode):






    console.log(({}).foo); // undefined





    When you use undefined in a relational operation like < or > with a number, it gets converted to a number, but the number value it gets is the special number NaN, which has the bizarre property of always causing comparisons to be false:






    console.log(NaN < 0);     // false
    console.log(NaN > 0); // false
    console.log(NaN === 0); // false
    console.log(NaN === NaN); // false!!





    What you can do about it



    Linter tools will often pick these things up in simple cases.



    Alternately, TypeScript provides a full static typing layer on top of JavaScript which can catch these sorts of errors.



    If you wanted (and this would probably be overkill), you could wrap a Proxy around your objects that threw a proactive error when you tried to read a property that didn't exist:






    function proactive(obj) {
    return new Proxy(obj, {
    get(target, propName, receiver) {
    if (!Reflect.has(target, propName)) {
    throw new TypeError(`Property '${propName}' not found on object`);
    }
    return Reflect.get(target, propName, receiver);
    }
    });
    }

    const a = proactive(["a", "b"]);
    a.push("c");
    for (let i = 0; i < a.length; ++i) {
    console.log(a[i]);
    }
    console.log(`Length is: ${a.lenght}`); // Note the typo

    .as-console-wrapper {
    max-height: 100% !important;
    }





    There's a significant runtime penalty, though.





    ¹ (that's a post on my anemic little blog)






    share|improve this answer





























      6














      You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime because you're calling a property that hasn't been created on the object. I'll suggest you to read What does "use strict" do in JavaScript, and what is the reasoning behind it?.






      share|improve this answer































        5














        The upper bound of the loop is specified as lenght, a typo for the local variable length. At runtime, lenght will evaluate to undefined, so the check 0 < undefined is false. Therefore the loop body is never executed.






        share|improve this answer



















        • 5




          Not answering the question
          – edc65
          Dec 3 '18 at 16:35



















        1














        By default, all objects in JavaScript are extensible, which means that you can add additional properties to them at any time simply by assigning a value to them.



        Arrays are no different; they're simply objects that are instances of the Array type (at least for the purposes of extensibility).



        In this case, had you added:



        Object.preventExtensions(arr);


        after creating the array, then in combination with 'use strict' this would have raised an error -- had you tried to write to a typo'd property. But for a read usage like this, there is still no error at all; you just get undefined.



        This is just one of the things you have to live with in a loosely-typed language; with the added flexibility comes added risk of bugs if you're not careful.






        share|improve this answer





















          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53586954%2fwhy-doesnt-javascript-warn-me-when-i-use-arr-lenght-misspelt-instead-of-arr-l%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          6 Answers
          6






          active

          oldest

          votes








          6 Answers
          6






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          72














          Because when you try to get a property that doesn't exist, it returns undefined, and 0 < undefined is false.






          let arr = [1, 2, 3, 4];
          console.log(arr.lenght) // undefined
          console.log(arr.qwerty) // undefined
          console.log(arr.lenght < 9999) // false
          console.log(arr.lenght > 9999) // false

          arr.length = 7 // <-- it's not a good idea
          for(let i = 0; i < arr.length; i++) {console.log(arr[i])}





          EDIT



          I said 'javascript is not a strongly typed language' and it is true. But this way of adding new properties it is a feature of prototype-based programming, as @Voo said.



          I also said .length=7 it's a bad idea. After reading a little more, in this case I still think it's a little weird to increase the length property after adding elements. Maybe it's fine to truncate, delete elements or empty an array, although in the latter case I would prefer arr= instead of arr.length=0.



          There are some interesting examples about length property in the Mozilla documentation.




          A JavaScript array's length property and numerical properties are
          connected. Several of the built-in array methods (e.g., join(),
          slice(), indexOf(), etc.) take into account the value of an array's
          length property when they're called. Other methods (e.g., push(),
          splice(), etc.) also result in updates to an array's length property.



          var fruits = ;
          fruits.push('banana', 'apple', 'peach');
          console.log(fruits.length); // 3


          When setting a property on a JavaScript array when the property is a
          valid array index and that index is outside the current bounds of the
          array, the engine will update the array's length property accordingly:



          fruits[5] = 'mango';
          console.log(fruits[5]); // 'mango'
          console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
          console.log(fruits.length); // 6


          Increasing the length.



          fruits.length = 10;
          console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
          console.log(fruits.length); // 10


          Decreasing the length property does, however, delete elements.



          fruits.length = 2;
          console.log(Object.keys(fruits)); // ['0', '1']
          console.log(fruits.length); // 2






          share|improve this answer



















          • 4




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            Dec 3 '18 at 8:27






          • 5




            PHP is also not a strongly typed language, yet it gives you a warning when you access a non-existing property. JavaScript, on the other hand, has no standard way to produce runtime warnings.
            – GOTO 0
            Dec 3 '18 at 8:37








          • 3




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            Dec 3 '18 at 10:33






          • 8




            @GOTO0 Yep, and you just summed up for me the irony in the way the dev world has been fawning over JavaScript for the last few years while at the same time pouring hate on PHP.
            – Spudley
            Dec 3 '18 at 13:22






          • 3




            Whether you get an error on accessing a non-existent property or not, has nothing to do if the language is strongly typed or not. This is more a feature of prototype based OOP languages.
            – Voo
            Dec 3 '18 at 14:18
















          72














          Because when you try to get a property that doesn't exist, it returns undefined, and 0 < undefined is false.






          let arr = [1, 2, 3, 4];
          console.log(arr.lenght) // undefined
          console.log(arr.qwerty) // undefined
          console.log(arr.lenght < 9999) // false
          console.log(arr.lenght > 9999) // false

          arr.length = 7 // <-- it's not a good idea
          for(let i = 0; i < arr.length; i++) {console.log(arr[i])}





          EDIT



          I said 'javascript is not a strongly typed language' and it is true. But this way of adding new properties it is a feature of prototype-based programming, as @Voo said.



          I also said .length=7 it's a bad idea. After reading a little more, in this case I still think it's a little weird to increase the length property after adding elements. Maybe it's fine to truncate, delete elements or empty an array, although in the latter case I would prefer arr= instead of arr.length=0.



          There are some interesting examples about length property in the Mozilla documentation.




          A JavaScript array's length property and numerical properties are
          connected. Several of the built-in array methods (e.g., join(),
          slice(), indexOf(), etc.) take into account the value of an array's
          length property when they're called. Other methods (e.g., push(),
          splice(), etc.) also result in updates to an array's length property.



          var fruits = ;
          fruits.push('banana', 'apple', 'peach');
          console.log(fruits.length); // 3


          When setting a property on a JavaScript array when the property is a
          valid array index and that index is outside the current bounds of the
          array, the engine will update the array's length property accordingly:



          fruits[5] = 'mango';
          console.log(fruits[5]); // 'mango'
          console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
          console.log(fruits.length); // 6


          Increasing the length.



          fruits.length = 10;
          console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
          console.log(fruits.length); // 10


          Decreasing the length property does, however, delete elements.



          fruits.length = 2;
          console.log(Object.keys(fruits)); // ['0', '1']
          console.log(fruits.length); // 2






          share|improve this answer



















          • 4




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            Dec 3 '18 at 8:27






          • 5




            PHP is also not a strongly typed language, yet it gives you a warning when you access a non-existing property. JavaScript, on the other hand, has no standard way to produce runtime warnings.
            – GOTO 0
            Dec 3 '18 at 8:37








          • 3




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            Dec 3 '18 at 10:33






          • 8




            @GOTO0 Yep, and you just summed up for me the irony in the way the dev world has been fawning over JavaScript for the last few years while at the same time pouring hate on PHP.
            – Spudley
            Dec 3 '18 at 13:22






          • 3




            Whether you get an error on accessing a non-existent property or not, has nothing to do if the language is strongly typed or not. This is more a feature of prototype based OOP languages.
            – Voo
            Dec 3 '18 at 14:18














          72












          72








          72






          Because when you try to get a property that doesn't exist, it returns undefined, and 0 < undefined is false.






          let arr = [1, 2, 3, 4];
          console.log(arr.lenght) // undefined
          console.log(arr.qwerty) // undefined
          console.log(arr.lenght < 9999) // false
          console.log(arr.lenght > 9999) // false

          arr.length = 7 // <-- it's not a good idea
          for(let i = 0; i < arr.length; i++) {console.log(arr[i])}





          EDIT



          I said 'javascript is not a strongly typed language' and it is true. But this way of adding new properties it is a feature of prototype-based programming, as @Voo said.



          I also said .length=7 it's a bad idea. After reading a little more, in this case I still think it's a little weird to increase the length property after adding elements. Maybe it's fine to truncate, delete elements or empty an array, although in the latter case I would prefer arr= instead of arr.length=0.



          There are some interesting examples about length property in the Mozilla documentation.




          A JavaScript array's length property and numerical properties are
          connected. Several of the built-in array methods (e.g., join(),
          slice(), indexOf(), etc.) take into account the value of an array's
          length property when they're called. Other methods (e.g., push(),
          splice(), etc.) also result in updates to an array's length property.



          var fruits = ;
          fruits.push('banana', 'apple', 'peach');
          console.log(fruits.length); // 3


          When setting a property on a JavaScript array when the property is a
          valid array index and that index is outside the current bounds of the
          array, the engine will update the array's length property accordingly:



          fruits[5] = 'mango';
          console.log(fruits[5]); // 'mango'
          console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
          console.log(fruits.length); // 6


          Increasing the length.



          fruits.length = 10;
          console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
          console.log(fruits.length); // 10


          Decreasing the length property does, however, delete elements.



          fruits.length = 2;
          console.log(Object.keys(fruits)); // ['0', '1']
          console.log(fruits.length); // 2






          share|improve this answer














          Because when you try to get a property that doesn't exist, it returns undefined, and 0 < undefined is false.






          let arr = [1, 2, 3, 4];
          console.log(arr.lenght) // undefined
          console.log(arr.qwerty) // undefined
          console.log(arr.lenght < 9999) // false
          console.log(arr.lenght > 9999) // false

          arr.length = 7 // <-- it's not a good idea
          for(let i = 0; i < arr.length; i++) {console.log(arr[i])}





          EDIT



          I said 'javascript is not a strongly typed language' and it is true. But this way of adding new properties it is a feature of prototype-based programming, as @Voo said.



          I also said .length=7 it's a bad idea. After reading a little more, in this case I still think it's a little weird to increase the length property after adding elements. Maybe it's fine to truncate, delete elements or empty an array, although in the latter case I would prefer arr= instead of arr.length=0.



          There are some interesting examples about length property in the Mozilla documentation.




          A JavaScript array's length property and numerical properties are
          connected. Several of the built-in array methods (e.g., join(),
          slice(), indexOf(), etc.) take into account the value of an array's
          length property when they're called. Other methods (e.g., push(),
          splice(), etc.) also result in updates to an array's length property.



          var fruits = ;
          fruits.push('banana', 'apple', 'peach');
          console.log(fruits.length); // 3


          When setting a property on a JavaScript array when the property is a
          valid array index and that index is outside the current bounds of the
          array, the engine will update the array's length property accordingly:



          fruits[5] = 'mango';
          console.log(fruits[5]); // 'mango'
          console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
          console.log(fruits.length); // 6


          Increasing the length.



          fruits.length = 10;
          console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
          console.log(fruits.length); // 10


          Decreasing the length property does, however, delete elements.



          fruits.length = 2;
          console.log(Object.keys(fruits)); // ['0', '1']
          console.log(fruits.length); // 2






          let arr = [1, 2, 3, 4];
          console.log(arr.lenght) // undefined
          console.log(arr.qwerty) // undefined
          console.log(arr.lenght < 9999) // false
          console.log(arr.lenght > 9999) // false

          arr.length = 7 // <-- it's not a good idea
          for(let i = 0; i < arr.length; i++) {console.log(arr[i])}





          let arr = [1, 2, 3, 4];
          console.log(arr.lenght) // undefined
          console.log(arr.qwerty) // undefined
          console.log(arr.lenght < 9999) // false
          console.log(arr.lenght > 9999) // false

          arr.length = 7 // <-- it's not a good idea
          for(let i = 0; i < arr.length; i++) {console.log(arr[i])}






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 3 '18 at 17:39

























          answered Dec 3 '18 at 3:12









          eag845

          878611




          878611








          • 4




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            Dec 3 '18 at 8:27






          • 5




            PHP is also not a strongly typed language, yet it gives you a warning when you access a non-existing property. JavaScript, on the other hand, has no standard way to produce runtime warnings.
            – GOTO 0
            Dec 3 '18 at 8:37








          • 3




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            Dec 3 '18 at 10:33






          • 8




            @GOTO0 Yep, and you just summed up for me the irony in the way the dev world has been fawning over JavaScript for the last few years while at the same time pouring hate on PHP.
            – Spudley
            Dec 3 '18 at 13:22






          • 3




            Whether you get an error on accessing a non-existent property or not, has nothing to do if the language is strongly typed or not. This is more a feature of prototype based OOP languages.
            – Voo
            Dec 3 '18 at 14:18














          • 4




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            Dec 3 '18 at 8:27






          • 5




            PHP is also not a strongly typed language, yet it gives you a warning when you access a non-existing property. JavaScript, on the other hand, has no standard way to produce runtime warnings.
            – GOTO 0
            Dec 3 '18 at 8:37








          • 3




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            Dec 3 '18 at 10:33






          • 8




            @GOTO0 Yep, and you just summed up for me the irony in the way the dev world has been fawning over JavaScript for the last few years while at the same time pouring hate on PHP.
            – Spudley
            Dec 3 '18 at 13:22






          • 3




            Whether you get an error on accessing a non-existent property or not, has nothing to do if the language is strongly typed or not. This is more a feature of prototype based OOP languages.
            – Voo
            Dec 3 '18 at 14:18








          4




          4




          Setting the .length of an array is a very common idea and there's nothing wrong with it.
          – Bergi
          Dec 3 '18 at 8:27




          Setting the .length of an array is a very common idea and there's nothing wrong with it.
          – Bergi
          Dec 3 '18 at 8:27




          5




          5




          PHP is also not a strongly typed language, yet it gives you a warning when you access a non-existing property. JavaScript, on the other hand, has no standard way to produce runtime warnings.
          – GOTO 0
          Dec 3 '18 at 8:37






          PHP is also not a strongly typed language, yet it gives you a warning when you access a non-existing property. JavaScript, on the other hand, has no standard way to produce runtime warnings.
          – GOTO 0
          Dec 3 '18 at 8:37






          3




          3




          @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
          – Bergi
          Dec 3 '18 at 10:33




          @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
          – Bergi
          Dec 3 '18 at 10:33




          8




          8




          @GOTO0 Yep, and you just summed up for me the irony in the way the dev world has been fawning over JavaScript for the last few years while at the same time pouring hate on PHP.
          – Spudley
          Dec 3 '18 at 13:22




          @GOTO0 Yep, and you just summed up for me the irony in the way the dev world has been fawning over JavaScript for the last few years while at the same time pouring hate on PHP.
          – Spudley
          Dec 3 '18 at 13:22




          3




          3




          Whether you get an error on accessing a non-existent property or not, has nothing to do if the language is strongly typed or not. This is more a feature of prototype based OOP languages.
          – Voo
          Dec 3 '18 at 14:18




          Whether you get an error on accessing a non-existent property or not, has nothing to do if the language is strongly typed or not. This is more a feature of prototype based OOP languages.
          – Voo
          Dec 3 '18 at 14:18













          14














          JavaScript arrays are treated as objects (though they are instances of Array). Hence, when you write arr.lenght, it treats lenght as a property of an object that is undefined. Hence, you don't get an error.



          It simply tries to get a property that is undefined. Also, in your case, the loop just does not execute as the condition of the loop is never satisfied.






          share|improve this answer




























            14














            JavaScript arrays are treated as objects (though they are instances of Array). Hence, when you write arr.lenght, it treats lenght as a property of an object that is undefined. Hence, you don't get an error.



            It simply tries to get a property that is undefined. Also, in your case, the loop just does not execute as the condition of the loop is never satisfied.






            share|improve this answer


























              14












              14








              14






              JavaScript arrays are treated as objects (though they are instances of Array). Hence, when you write arr.lenght, it treats lenght as a property of an object that is undefined. Hence, you don't get an error.



              It simply tries to get a property that is undefined. Also, in your case, the loop just does not execute as the condition of the loop is never satisfied.






              share|improve this answer














              JavaScript arrays are treated as objects (though they are instances of Array). Hence, when you write arr.lenght, it treats lenght as a property of an object that is undefined. Hence, you don't get an error.



              It simply tries to get a property that is undefined. Also, in your case, the loop just does not execute as the condition of the loop is never satisfied.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 3 '18 at 21:47









              Peter Mortensen

              13.5k1983111




              13.5k1983111










              answered Dec 3 '18 at 3:15









              Rohan Dhar

              1,025317




              1,025317























                  8














                  Why



                  Standard JavaScript arrays aren't really arrays at all¹, they're objects, and if you read an object property that doesn't exist (like lenght), you get the value undefined (even in strict mode):






                  console.log(({}).foo); // undefined





                  When you use undefined in a relational operation like < or > with a number, it gets converted to a number, but the number value it gets is the special number NaN, which has the bizarre property of always causing comparisons to be false:






                  console.log(NaN < 0);     // false
                  console.log(NaN > 0); // false
                  console.log(NaN === 0); // false
                  console.log(NaN === NaN); // false!!





                  What you can do about it



                  Linter tools will often pick these things up in simple cases.



                  Alternately, TypeScript provides a full static typing layer on top of JavaScript which can catch these sorts of errors.



                  If you wanted (and this would probably be overkill), you could wrap a Proxy around your objects that threw a proactive error when you tried to read a property that didn't exist:






                  function proactive(obj) {
                  return new Proxy(obj, {
                  get(target, propName, receiver) {
                  if (!Reflect.has(target, propName)) {
                  throw new TypeError(`Property '${propName}' not found on object`);
                  }
                  return Reflect.get(target, propName, receiver);
                  }
                  });
                  }

                  const a = proactive(["a", "b"]);
                  a.push("c");
                  for (let i = 0; i < a.length; ++i) {
                  console.log(a[i]);
                  }
                  console.log(`Length is: ${a.lenght}`); // Note the typo

                  .as-console-wrapper {
                  max-height: 100% !important;
                  }





                  There's a significant runtime penalty, though.





                  ¹ (that's a post on my anemic little blog)






                  share|improve this answer


























                    8














                    Why



                    Standard JavaScript arrays aren't really arrays at all¹, they're objects, and if you read an object property that doesn't exist (like lenght), you get the value undefined (even in strict mode):






                    console.log(({}).foo); // undefined





                    When you use undefined in a relational operation like < or > with a number, it gets converted to a number, but the number value it gets is the special number NaN, which has the bizarre property of always causing comparisons to be false:






                    console.log(NaN < 0);     // false
                    console.log(NaN > 0); // false
                    console.log(NaN === 0); // false
                    console.log(NaN === NaN); // false!!





                    What you can do about it



                    Linter tools will often pick these things up in simple cases.



                    Alternately, TypeScript provides a full static typing layer on top of JavaScript which can catch these sorts of errors.



                    If you wanted (and this would probably be overkill), you could wrap a Proxy around your objects that threw a proactive error when you tried to read a property that didn't exist:






                    function proactive(obj) {
                    return new Proxy(obj, {
                    get(target, propName, receiver) {
                    if (!Reflect.has(target, propName)) {
                    throw new TypeError(`Property '${propName}' not found on object`);
                    }
                    return Reflect.get(target, propName, receiver);
                    }
                    });
                    }

                    const a = proactive(["a", "b"]);
                    a.push("c");
                    for (let i = 0; i < a.length; ++i) {
                    console.log(a[i]);
                    }
                    console.log(`Length is: ${a.lenght}`); // Note the typo

                    .as-console-wrapper {
                    max-height: 100% !important;
                    }





                    There's a significant runtime penalty, though.





                    ¹ (that's a post on my anemic little blog)






                    share|improve this answer
























                      8












                      8








                      8






                      Why



                      Standard JavaScript arrays aren't really arrays at all¹, they're objects, and if you read an object property that doesn't exist (like lenght), you get the value undefined (even in strict mode):






                      console.log(({}).foo); // undefined





                      When you use undefined in a relational operation like < or > with a number, it gets converted to a number, but the number value it gets is the special number NaN, which has the bizarre property of always causing comparisons to be false:






                      console.log(NaN < 0);     // false
                      console.log(NaN > 0); // false
                      console.log(NaN === 0); // false
                      console.log(NaN === NaN); // false!!





                      What you can do about it



                      Linter tools will often pick these things up in simple cases.



                      Alternately, TypeScript provides a full static typing layer on top of JavaScript which can catch these sorts of errors.



                      If you wanted (and this would probably be overkill), you could wrap a Proxy around your objects that threw a proactive error when you tried to read a property that didn't exist:






                      function proactive(obj) {
                      return new Proxy(obj, {
                      get(target, propName, receiver) {
                      if (!Reflect.has(target, propName)) {
                      throw new TypeError(`Property '${propName}' not found on object`);
                      }
                      return Reflect.get(target, propName, receiver);
                      }
                      });
                      }

                      const a = proactive(["a", "b"]);
                      a.push("c");
                      for (let i = 0; i < a.length; ++i) {
                      console.log(a[i]);
                      }
                      console.log(`Length is: ${a.lenght}`); // Note the typo

                      .as-console-wrapper {
                      max-height: 100% !important;
                      }





                      There's a significant runtime penalty, though.





                      ¹ (that's a post on my anemic little blog)






                      share|improve this answer












                      Why



                      Standard JavaScript arrays aren't really arrays at all¹, they're objects, and if you read an object property that doesn't exist (like lenght), you get the value undefined (even in strict mode):






                      console.log(({}).foo); // undefined





                      When you use undefined in a relational operation like < or > with a number, it gets converted to a number, but the number value it gets is the special number NaN, which has the bizarre property of always causing comparisons to be false:






                      console.log(NaN < 0);     // false
                      console.log(NaN > 0); // false
                      console.log(NaN === 0); // false
                      console.log(NaN === NaN); // false!!





                      What you can do about it



                      Linter tools will often pick these things up in simple cases.



                      Alternately, TypeScript provides a full static typing layer on top of JavaScript which can catch these sorts of errors.



                      If you wanted (and this would probably be overkill), you could wrap a Proxy around your objects that threw a proactive error when you tried to read a property that didn't exist:






                      function proactive(obj) {
                      return new Proxy(obj, {
                      get(target, propName, receiver) {
                      if (!Reflect.has(target, propName)) {
                      throw new TypeError(`Property '${propName}' not found on object`);
                      }
                      return Reflect.get(target, propName, receiver);
                      }
                      });
                      }

                      const a = proactive(["a", "b"]);
                      a.push("c");
                      for (let i = 0; i < a.length; ++i) {
                      console.log(a[i]);
                      }
                      console.log(`Length is: ${a.lenght}`); // Note the typo

                      .as-console-wrapper {
                      max-height: 100% !important;
                      }





                      There's a significant runtime penalty, though.





                      ¹ (that's a post on my anemic little blog)






                      console.log(({}).foo); // undefined





                      console.log(({}).foo); // undefined





                      console.log(NaN < 0);     // false
                      console.log(NaN > 0); // false
                      console.log(NaN === 0); // false
                      console.log(NaN === NaN); // false!!





                      console.log(NaN < 0);     // false
                      console.log(NaN > 0); // false
                      console.log(NaN === 0); // false
                      console.log(NaN === NaN); // false!!





                      function proactive(obj) {
                      return new Proxy(obj, {
                      get(target, propName, receiver) {
                      if (!Reflect.has(target, propName)) {
                      throw new TypeError(`Property '${propName}' not found on object`);
                      }
                      return Reflect.get(target, propName, receiver);
                      }
                      });
                      }

                      const a = proactive(["a", "b"]);
                      a.push("c");
                      for (let i = 0; i < a.length; ++i) {
                      console.log(a[i]);
                      }
                      console.log(`Length is: ${a.lenght}`); // Note the typo

                      .as-console-wrapper {
                      max-height: 100% !important;
                      }





                      function proactive(obj) {
                      return new Proxy(obj, {
                      get(target, propName, receiver) {
                      if (!Reflect.has(target, propName)) {
                      throw new TypeError(`Property '${propName}' not found on object`);
                      }
                      return Reflect.get(target, propName, receiver);
                      }
                      });
                      }

                      const a = proactive(["a", "b"]);
                      a.push("c");
                      for (let i = 0; i < a.length; ++i) {
                      console.log(a[i]);
                      }
                      console.log(`Length is: ${a.lenght}`); // Note the typo

                      .as-console-wrapper {
                      max-height: 100% !important;
                      }






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Dec 3 '18 at 17:28









                      T.J. Crowder

                      678k12111991296




                      678k12111991296























                          6














                          You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime because you're calling a property that hasn't been created on the object. I'll suggest you to read What does "use strict" do in JavaScript, and what is the reasoning behind it?.






                          share|improve this answer




























                            6














                            You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime because you're calling a property that hasn't been created on the object. I'll suggest you to read What does "use strict" do in JavaScript, and what is the reasoning behind it?.






                            share|improve this answer


























                              6












                              6








                              6






                              You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime because you're calling a property that hasn't been created on the object. I'll suggest you to read What does "use strict" do in JavaScript, and what is the reasoning behind it?.






                              share|improve this answer














                              You could easily add new properties to arr object, JavaScript won't warn you about it, instead it will try to find the property you're calling, and if it didn't find anything such result will be undefined, so the comparison is actually i < undefined everytime because you're calling a property that hasn't been created on the object. I'll suggest you to read What does "use strict" do in JavaScript, and what is the reasoning behind it?.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Dec 4 '18 at 13:18

























                              answered Dec 3 '18 at 3:20









                              mmontoya

                              3539




                              3539























                                  5














                                  The upper bound of the loop is specified as lenght, a typo for the local variable length. At runtime, lenght will evaluate to undefined, so the check 0 < undefined is false. Therefore the loop body is never executed.






                                  share|improve this answer



















                                  • 5




                                    Not answering the question
                                    – edc65
                                    Dec 3 '18 at 16:35
















                                  5














                                  The upper bound of the loop is specified as lenght, a typo for the local variable length. At runtime, lenght will evaluate to undefined, so the check 0 < undefined is false. Therefore the loop body is never executed.






                                  share|improve this answer



















                                  • 5




                                    Not answering the question
                                    – edc65
                                    Dec 3 '18 at 16:35














                                  5












                                  5








                                  5






                                  The upper bound of the loop is specified as lenght, a typo for the local variable length. At runtime, lenght will evaluate to undefined, so the check 0 < undefined is false. Therefore the loop body is never executed.






                                  share|improve this answer














                                  The upper bound of the loop is specified as lenght, a typo for the local variable length. At runtime, lenght will evaluate to undefined, so the check 0 < undefined is false. Therefore the loop body is never executed.







                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Dec 4 '18 at 23:45

























                                  answered Dec 3 '18 at 3:13









                                  fuzz

                                  15.2k17108183




                                  15.2k17108183








                                  • 5




                                    Not answering the question
                                    – edc65
                                    Dec 3 '18 at 16:35














                                  • 5




                                    Not answering the question
                                    – edc65
                                    Dec 3 '18 at 16:35








                                  5




                                  5




                                  Not answering the question
                                  – edc65
                                  Dec 3 '18 at 16:35




                                  Not answering the question
                                  – edc65
                                  Dec 3 '18 at 16:35











                                  1














                                  By default, all objects in JavaScript are extensible, which means that you can add additional properties to them at any time simply by assigning a value to them.



                                  Arrays are no different; they're simply objects that are instances of the Array type (at least for the purposes of extensibility).



                                  In this case, had you added:



                                  Object.preventExtensions(arr);


                                  after creating the array, then in combination with 'use strict' this would have raised an error -- had you tried to write to a typo'd property. But for a read usage like this, there is still no error at all; you just get undefined.



                                  This is just one of the things you have to live with in a loosely-typed language; with the added flexibility comes added risk of bugs if you're not careful.






                                  share|improve this answer


























                                    1














                                    By default, all objects in JavaScript are extensible, which means that you can add additional properties to them at any time simply by assigning a value to them.



                                    Arrays are no different; they're simply objects that are instances of the Array type (at least for the purposes of extensibility).



                                    In this case, had you added:



                                    Object.preventExtensions(arr);


                                    after creating the array, then in combination with 'use strict' this would have raised an error -- had you tried to write to a typo'd property. But for a read usage like this, there is still no error at all; you just get undefined.



                                    This is just one of the things you have to live with in a loosely-typed language; with the added flexibility comes added risk of bugs if you're not careful.






                                    share|improve this answer
























                                      1












                                      1








                                      1






                                      By default, all objects in JavaScript are extensible, which means that you can add additional properties to them at any time simply by assigning a value to them.



                                      Arrays are no different; they're simply objects that are instances of the Array type (at least for the purposes of extensibility).



                                      In this case, had you added:



                                      Object.preventExtensions(arr);


                                      after creating the array, then in combination with 'use strict' this would have raised an error -- had you tried to write to a typo'd property. But for a read usage like this, there is still no error at all; you just get undefined.



                                      This is just one of the things you have to live with in a loosely-typed language; with the added flexibility comes added risk of bugs if you're not careful.






                                      share|improve this answer












                                      By default, all objects in JavaScript are extensible, which means that you can add additional properties to them at any time simply by assigning a value to them.



                                      Arrays are no different; they're simply objects that are instances of the Array type (at least for the purposes of extensibility).



                                      In this case, had you added:



                                      Object.preventExtensions(arr);


                                      after creating the array, then in combination with 'use strict' this would have raised an error -- had you tried to write to a typo'd property. But for a read usage like this, there is still no error at all; you just get undefined.



                                      This is just one of the things you have to live with in a loosely-typed language; with the added flexibility comes added risk of bugs if you're not careful.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Dec 4 '18 at 1:34









                                      Miral

                                      7,99823268




                                      7,99823268






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.





                                          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                          Please pay close attention to the following guidance:


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53586954%2fwhy-doesnt-javascript-warn-me-when-i-use-arr-lenght-misspelt-instead-of-arr-l%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          How to change which sound is reproduced for terminal bell?

                                          Can I use Tabulator js library in my java Spring + Thymeleaf project?

                                          Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents