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











up vote
56
down vote

favorite
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




















  • 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 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 at 3:20








  • 47




    Because you aren't using TypeScript.
    – Ian Kemp
    Dec 3 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 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 at 14:44















up vote
56
down vote

favorite
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




















  • 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 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 at 3:20








  • 47




    Because you aren't using TypeScript.
    – Ian Kemp
    Dec 3 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 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 at 14:44













up vote
56
down vote

favorite
4









up vote
56
down vote

favorite
4






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 at 23:24









Peter Mortensen

13.4k1983111




13.4k1983111










asked Dec 3 at 3:09









MangoLato

368210




368210








  • 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 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 at 3:20








  • 47




    Because you aren't using TypeScript.
    – Ian Kemp
    Dec 3 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 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 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 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 at 3:20








  • 47




    Because you aren't using TypeScript.
    – Ian Kemp
    Dec 3 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 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 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 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 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 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 at 3:20






47




47




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




Because you aren't using TypeScript.
– Ian Kemp
Dec 3 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 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 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 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 at 14:44












6 Answers
6






active

oldest

votes

















up vote
71
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



















  • 4




    Setting the .length of an array is a very common idea and there's nothing wrong with it.
    – Bergi
    Dec 3 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 at 8:37








  • 3




    @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
    – Bergi
    Dec 3 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 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 at 14:18


















up vote
13
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













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






























        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 0 < undefined is false. Therefore the loop body is never executed.






        share|improve this answer



















        • 5




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


















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



















          • 4




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            Dec 3 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 at 8:37








          • 3




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            Dec 3 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 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 at 14:18















          up vote
          71
          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



















          • 4




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            Dec 3 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 at 8:37








          • 3




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            Dec 3 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 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 at 14:18













          up vote
          71
          down vote



          accepted







          up vote
          71
          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 Dec 3 at 17:39

























          answered Dec 3 at 3:12









          eag845

          868611




          868611








          • 4




            Setting the .length of an array is a very common idea and there's nothing wrong with it.
            – Bergi
            Dec 3 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 at 8:37








          • 3




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            Dec 3 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 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 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 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 at 8:37








          • 3




            @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
            – Bergi
            Dec 3 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 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 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 at 8:27




          Setting the .length of an array is a very common idea and there's nothing wrong with it.
          – Bergi
          Dec 3 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 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 at 8:37






          3




          3




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




          @JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
          – Bergi
          Dec 3 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 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 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 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 at 14:18












          up vote
          13
          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
            13
            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
              13
              down vote










              up vote
              13
              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 Dec 3 at 21:47









              Peter Mortensen

              13.4k1983111




              13.4k1983111










              answered Dec 3 at 3:15









              Rohan Dhar

              827216




              827216






















                  up vote
                  7
                  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
                    7
                    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
                      7
                      down vote










                      up vote
                      7
                      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 Dec 3 at 17:28









                      T.J. Crowder

                      673k11811901286




                      673k11811901286






















                          up vote
                          6
                          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 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



























                            up vote
                            6
                            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 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

























                              up vote
                              6
                              down vote










                              up vote
                              6
                              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 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 at 13:18

























                              answered Dec 3 at 3:20









                              mmontoya

                              3539




                              3539






















                                  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 0 < undefined is false. Therefore the loop body is never executed.






                                  share|improve this answer



















                                  • 5




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















                                  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 0 < undefined is false. Therefore the loop body is never executed.






                                  share|improve this answer



















                                  • 5




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













                                  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 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 at 23:45

























                                  answered Dec 3 at 3:13









                                  fuzz

                                  15.1k17108183




                                  15.1k17108183








                                  • 5




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














                                  • 5




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








                                  5




                                  5




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




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










                                  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 Dec 4 at 1:34









                                      Miral

                                      7,95323268




                                      7,95323268






























                                          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

                                          flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

                                          Mangá

                                          Eduardo VII do Reino Unido