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
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]);
}
javascript
|
show 2 more comments
up vote
28
down vote
favorite
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]);
}
javascript
3
You could easily add new properties toarr
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 actuallyi < 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
28
Because you aren't using TypeScript.
– Ian Kemp
19 hours ago
4
It also does not warn you aboutwindow.sdjkhednrgj
for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
– usr
16 hours ago
1
If it would give a warning about these things, it would also give a warning every time you wroteif (someObject.someProperty==undefined)
when the property was undefined...
– Mr Lister
13 hours ago
|
show 2 more comments
up vote
28
down vote
favorite
up vote
28
down vote
favorite
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]);
}
javascript
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
javascript
edited 1 hour ago
asked yesterday
MangoLato
15826
15826
3
You could easily add new properties toarr
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 actuallyi < 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
28
Because you aren't using TypeScript.
– Ian Kemp
19 hours ago
4
It also does not warn you aboutwindow.sdjkhednrgj
for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
– usr
16 hours ago
1
If it would give a warning about these things, it would also give a warning every time you wroteif (someObject.someProperty==undefined)
when the property was undefined...
– Mr Lister
13 hours ago
|
show 2 more comments
3
You could easily add new properties toarr
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 actuallyi < 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
28
Because you aren't using TypeScript.
– Ian Kemp
19 hours ago
4
It also does not warn you aboutwindow.sdjkhednrgj
for example. This just evaluates to undefined. (Is this good language design? It has up and downsides. Can certainly cause brittleness.)
– usr
16 hours ago
1
If it would give a warning about these things, it would also give a warning every time you wroteif (someObject.someProperty==undefined)
when the property was undefined...
– Mr Lister
13 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
28
28
Because you aren't using TypeScript.
– Ian Kemp
19 hours ago
Because you aren't using TypeScript.
– Ian Kemp
19 hours ago
4
4
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
16 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
16 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
13 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
13 hours ago
|
show 2 more comments
6 Answers
6
active
oldest
votes
up vote
49
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
2
Setting the.length
of an array is a very common idea and there's nothing wrong with it.
– Bergi
19 hours ago
2
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
19 hours ago
2
@JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
– Bergi
17 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
14 hours ago
2
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
13 hours ago
|
show 6 more comments
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.
add a comment |
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.
3
Not answering the question
– edc65
11 hours ago
add a comment |
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?.
New contributor
add a comment |
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)
add a comment |
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.
add a comment |
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
49
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
2
Setting the.length
of an array is a very common idea and there's nothing wrong with it.
– Bergi
19 hours ago
2
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
19 hours ago
2
@JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
– Bergi
17 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
14 hours ago
2
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
13 hours ago
|
show 6 more comments
up vote
49
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
2
Setting the.length
of an array is a very common idea and there's nothing wrong with it.
– Bergi
19 hours ago
2
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
19 hours ago
2
@JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
– Bergi
17 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
14 hours ago
2
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
13 hours ago
|
show 6 more comments
up vote
49
down vote
accepted
up vote
49
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
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])}
edited 10 hours ago
answered yesterday
eag845
529611
529611
2
Setting the.length
of an array is a very common idea and there's nothing wrong with it.
– Bergi
19 hours ago
2
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
19 hours ago
2
@JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
– Bergi
17 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
14 hours ago
2
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
13 hours ago
|
show 6 more comments
2
Setting the.length
of an array is a very common idea and there's nothing wrong with it.
– Bergi
19 hours ago
2
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
19 hours ago
2
@JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
– Bergi
17 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
14 hours ago
2
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
13 hours ago
2
2
Setting the
.length
of an array is a very common idea and there's nothing wrong with it.– Bergi
19 hours ago
Setting the
.length
of an array is a very common idea and there's nothing wrong with it.– Bergi
19 hours ago
2
2
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
19 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
19 hours ago
2
2
@JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
– Bergi
17 hours ago
@JacobRaihle To empty, otherwise truncate, or (rarely) preallocate it.
– Bergi
17 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
14 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
14 hours ago
2
2
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
13 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
13 hours ago
|
show 6 more comments
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.
add a comment |
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.
add a comment |
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.
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.
edited 6 hours ago
Peter Mortensen
13.3k1983111
13.3k1983111
answered yesterday
Rohan Dhar
722214
722214
add a comment |
add a comment |
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.
3
Not answering the question
– edc65
11 hours ago
add a comment |
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.
3
Not answering the question
– edc65
11 hours ago
add a comment |
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.
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.
edited 16 hours ago
Cœur
17.1k9102140
17.1k9102140
answered yesterday
fuzz
15k17108183
15k17108183
3
Not answering the question
– edc65
11 hours ago
add a comment |
3
Not answering the question
– edc65
11 hours ago
3
3
Not answering the question
– edc65
11 hours ago
Not answering the question
– edc65
11 hours ago
add a comment |
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?.
New contributor
add a comment |
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?.
New contributor
add a comment |
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?.
New contributor
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?.
New contributor
New contributor
answered yesterday
mmontoya
1838
1838
New contributor
New contributor
add a comment |
add a comment |
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)
add a comment |
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)
add a comment |
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)
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;
}
answered 10 hours ago
T.J. Crowder
671k11611841283
671k11611841283
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered 2 hours ago
Miral
7,94323168
7,94323168
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 actuallyi < 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
28
Because you aren't using TypeScript.
– Ian Kemp
19 hours ago
4
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
16 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
13 hours ago