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
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]);
}
javascript
|
show 4 more comments
up vote
56
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.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]);
}
javascript
6
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
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 aboutwindow.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 wroteif (someObject.someProperty==undefined)
when the property was undefined...
– Mr Lister
Dec 3 at 14:44
|
show 4 more comments
up vote
56
down vote
favorite
up vote
56
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.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]);
}
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.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
javascript
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 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
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 aboutwindow.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 wroteif (someObject.someProperty==undefined)
when the property was undefined...
– Mr Lister
Dec 3 at 14:44
|
show 4 more comments
6
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
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 aboutwindow.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 wroteif (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
|
show 4 more comments
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
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
|
show 6 more comments
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.
add a comment |
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)
add a comment |
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?.
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 0 < undefined
is false
. Therefore the loop body is never executed.
5
Not answering the question
– edc65
Dec 3 at 16:35
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 |
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
});
}
});
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
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
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
|
show 6 more comments
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
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
|
show 6 more comments
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
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 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
|
show 6 more comments
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
|
show 6 more comments
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.
add a comment |
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.
add a comment |
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.
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 Dec 3 at 21:47
Peter Mortensen
13.4k1983111
13.4k1983111
answered Dec 3 at 3:15
Rohan Dhar
827216
827216
add a comment |
add a comment |
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)
add a comment |
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)
add a comment |
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)
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 Dec 3 at 17:28
T.J. Crowder
673k11811901286
673k11811901286
add a comment |
add a comment |
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?.
add a comment |
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?.
add a comment |
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?.
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?.
edited Dec 4 at 13:18
answered Dec 3 at 3:20
mmontoya
3539
3539
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 0 < undefined
is false
. Therefore the loop body is never executed.
5
Not answering the question
– edc65
Dec 3 at 16:35
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 0 < undefined
is false
. Therefore the loop body is never executed.
5
Not answering the question
– edc65
Dec 3 at 16:35
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 0 < undefined
is false
. Therefore 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 0 < undefined
is false
. Therefore the loop body is never executed.
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
add a comment |
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
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 Dec 4 at 1:34
Miral
7,95323268
7,95323268
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
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 actuallyi < 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