Почему 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 в качестве транспилятора...