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











up vote
28
down vote

favorite
3












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 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




















  • 3




    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
    yesterday






  • 5




    Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
    – charlietfl
    yesterday








  • 31




    Because you aren't using TypeScript.
    – Ian Kemp
    23 hours ago






  • 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
    19 hours ago








  • 1




    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
    16 hours ago















up vote
28
down vote

favorite
3












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 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




















  • 3




    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
    yesterday






  • 5




    Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
    – charlietfl
    yesterday








  • 31




    Because you aren't using TypeScript.
    – Ian Kemp
    23 hours ago






  • 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
    19 hours ago








  • 1




    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
    16 hours ago













up vote
28
down vote

favorite
3









up vote
28
down vote

favorite
3






3





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 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 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 4 hours ago

























asked yesterday









MangoLato

15826




15826








  • 3




    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
    yesterday






  • 5




    Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
    – charlietfl
    yesterday








  • 31




    Because you aren't using TypeScript.
    – Ian Kemp
    23 hours ago






  • 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
    19 hours ago








  • 1




    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
    16 hours ago














  • 3




    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
    yesterday






  • 5




    Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
    – charlietfl
    yesterday








  • 31




    Because you aren't using TypeScript.
    – Ian Kemp
    23 hours ago






  • 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
    19 hours ago








  • 1




    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
    16 hours ago








3




3




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
yesterday




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
yesterday




5




5




Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
– charlietfl
yesterday






Simple answer is...because it's a loosely typed language. Everyone has made property name typos. Lick your wounds and move on
– charlietfl
yesterday






31




31




Because you aren't using TypeScript.
– Ian Kemp
23 hours ago




Because you aren't using TypeScript.
– Ian Kemp
23 hours ago




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
19 hours ago






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
19 hours ago






1




1




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
16 hours ago




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
16 hours ago












6 Answers
6






active

oldest

votes

















up vote
52
down vote



accepted










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



















  • 2




    Setting the .length of an array is a very common idea and there's nothing wrong with it.
    – Bergi
    22 hours ago






  • 3




    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
    22 hours ago








  • 2




    @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
    – Bergi
    20 hours ago






  • 4




    @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
    18 hours ago






  • 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
    17 hours ago


















up vote
7
down vote













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






























    up vote
    5
    down vote













    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 i < lenght will always fail, and the loop body is never executed.






    share|improve this answer



















    • 3




      Not answering the question
      – edc65
      14 hours ago


















    up vote
    4
    down vote













    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 haven'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








    New contributor




    mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.

























      up vote
      2
      down vote













      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




























        up vote
        1
        down vote













        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',
          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








          up vote
          52
          down vote



          accepted










          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



















          • 2




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            22 hours ago






          • 3




            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
            22 hours ago








          • 2




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            20 hours ago






          • 4




            @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
            18 hours ago






          • 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
            17 hours ago















          up vote
          52
          down vote



          accepted










          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



















          • 2




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            22 hours ago






          • 3




            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
            22 hours ago








          • 2




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            20 hours ago






          • 4




            @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
            18 hours ago






          • 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
            17 hours ago













          up vote
          52
          down vote



          accepted







          up vote
          52
          down vote



          accepted






          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 13 hours ago

























          answered yesterday









          eag845

          559611




          559611








          • 2




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            22 hours ago






          • 3




            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
            22 hours ago








          • 2




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            20 hours ago






          • 4




            @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
            18 hours ago






          • 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
            17 hours ago














          • 2




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            22 hours ago






          • 3




            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
            22 hours ago








          • 2




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            20 hours ago






          • 4




            @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
            18 hours ago






          • 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
            17 hours ago








          2




          2




          Setting the .length of an array is a very common idea and there's nothing wrong with it.
          – Bergi
          22 hours ago




          Setting the .length of an array is a very common idea and there's nothing wrong with it.
          – Bergi
          22 hours ago




          3




          3




          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
          22 hours ago






          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
          22 hours ago






          2




          2




          @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
          – Bergi
          20 hours ago




          @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
          – Bergi
          20 hours ago




          4




          4




          @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
          18 hours ago




          @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
          18 hours ago




          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
          17 hours ago




          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
          17 hours ago












          up vote
          7
          down vote













          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



























            up vote
            7
            down vote













            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

























              up vote
              7
              down vote










              up vote
              7
              down vote









              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 9 hours ago









              Peter Mortensen

              13.3k1983111




              13.3k1983111










              answered yesterday









              Rohan Dhar

              722214




              722214






















                  up vote
                  5
                  down vote













                  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 i < lenght will always fail, and the loop body is never executed.






                  share|improve this answer



















                  • 3




                    Not answering the question
                    – edc65
                    14 hours ago















                  up vote
                  5
                  down vote













                  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 i < lenght will always fail, and the loop body is never executed.






                  share|improve this answer



















                  • 3




                    Not answering the question
                    – edc65
                    14 hours ago













                  up vote
                  5
                  down vote










                  up vote
                  5
                  down vote









                  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 i < lenght will always fail, and 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 i < lenght will always fail, and the loop body is never executed.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 19 hours ago









                  Cœur

                  17.1k9102140




                  17.1k9102140










                  answered yesterday









                  fuzz

                  15k17108183




                  15k17108183








                  • 3




                    Not answering the question
                    – edc65
                    14 hours ago














                  • 3




                    Not answering the question
                    – edc65
                    14 hours ago








                  3




                  3




                  Not answering the question
                  – edc65
                  14 hours ago




                  Not answering the question
                  – edc65
                  14 hours ago










                  up vote
                  4
                  down vote













                  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 haven'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








                  New contributor




                  mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.






















                    up vote
                    4
                    down vote













                    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 haven'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








                    New contributor




                    mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                    Check out our Code of Conduct.




















                      up vote
                      4
                      down vote










                      up vote
                      4
                      down vote









                      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 haven'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








                      New contributor




                      mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                      Check out our Code of Conduct.









                      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 haven'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








                      New contributor




                      mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                      Check out our Code of Conduct.









                      share|improve this answer



                      share|improve this answer






                      New contributor




                      mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                      Check out our Code of Conduct.









                      answered yesterday









                      mmontoya

                      1838




                      1838




                      New contributor




                      mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                      Check out our Code of Conduct.





                      New contributor





                      mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                      Check out our Code of Conduct.






                      mmontoya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                      Check out our Code of Conduct.






















                          up vote
                          2
                          down vote













                          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

























                            up vote
                            2
                            down vote













                            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























                              up vote
                              2
                              down vote










                              up vote
                              2
                              down vote









                              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 13 hours ago









                              T.J. Crowder

                              671k11611841283




                              671k11611841283






















                                  up vote
                                  1
                                  down vote













                                  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

























                                    up vote
                                    1
                                    down vote













                                    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























                                      up vote
                                      1
                                      down vote










                                      up vote
                                      1
                                      down vote









                                      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 5 hours ago









                                      Miral

                                      7,94323168




                                      7,94323168






























                                          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

                                          What visual should I use to simply compare current year value vs last year in Power BI desktop

                                          Alexandru Averescu

                                          Trompette piccolo