Почему JavaScript не предупреждает меня, когда я использую arr.lenght(misspelt) вместо arr.length в цикле? Я также использую строгий режим
Я потратил часы, чтобы узнать, что я пропустил слово .length
как .lenght
. Он может нормально работать без предупреждения. Зачем...?
Я использую 'use strict'
и запускаю Node.js 10.13.0.
Код:
'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}
Ответы
Ответ 1
Потому что, когда вы пытаетесь получить свойство, которое не существует, оно возвращает undefined
, а 0 < undefined
- 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 not a good idea
for(let i = 0; i < arr.length; i++) {console.log(arr[i])}
Ответ 2
Массивы JavaScript рассматриваются как объекты (хотя они являются экземплярами массива). Следовательно, когда вы пишете arr.lenght
, он обрабатывает lenght
как свойство объекта, который не определен. Следовательно, вы не получите ошибку.
Он просто пытается получить свойство, которое не определено. Кроме того, в вашем случае цикл просто не выполняется, поскольку условие цикла никогда не выполняется.
Ответ 3
Вы можете легко добавить новые свойства к объекту arr
, JavaScript не предупредит вас об этом, вместо этого он попытается найти свойство, которое вы вызываете, и если он не найдет ничего такого, результат будет неопределенным, поэтому сравнение фактически i < undefined
everytime, потому что вы вызываете свойство, которое не было создано на объекте. Я предлагаю вам прочитать, что делает "использовать строгий" в JavaScript, и каковы причины этого? ,
Ответ 4
Верхняя граница цикла задается как lenght
, опечатка для локальной переменной длины. Во время выполнения lenght
будет вычисляться до undefined
, поэтому проверка 0 < undefined
равна false
. Поэтому тело цикла никогда не выполняется.
Ответ 5
Зачем
Стандартные массивы JavaScript на самом деле не являются массивами ¹, они являются объектами, и если вы читаете свойство объекта, которое не существует (например, lenght
), вы получаете значение undefined
(даже в строгом режиме):
console.log(({}).foo); // undefined
Ответ 6
По умолчанию все объекты в JavaScript расширяемы, что означает, что вы можете добавлять к ним дополнительные свойства в любое время, просто присваивая им значение.
Массивы ничем не отличаются; это просто объекты, которые являются экземплярами типа Array
(по крайней мере, в целях расширяемости).
В этом случае, если бы вы добавили:
Object.preventExtensions(arr);
после создания массива, тогда в сочетании с 'use strict'
это вызвало бы ошибку - если бы вы попытались написать свойство typo'd. Но для прочитанного использования, подобного этому, все еще нет ошибки; вы просто получите undefined
.
Это всего лишь одна из вещей, с которыми вам нужно жить на свободно типизированном языке; с добавленной гибкостью добавляется риск ошибок, если вы не будете осторожны.
Ответ 7
Это происходит потому, что когда вы пытаетесь получить свойство, которого не существует, оно возвращает undefined, а 0 <undefined - false.
Установка длины массива - очень распространенная идея, и в этом нет ничего плохого. Может быть, это прекрасно, чтобы усечь, удалить элементы или очистить массив, хотя в последнем случае я предпочел бы arr = [] вместо arr.length = 0.
Вам просто нужно использовать TypScript.
Ответ 8
Эта проблема устраняется при использовании TypeScript в качестве транспилятора...