Является ли длина строки Javascript постоянной?

Я новичок в JS и понимаю, что длина считается собственностью. Но я получил комментарий, чтобы не использовать str.length в цикле:

for (i=0; i<str.length; i++){...}

против

var len = str.length;
for (i=0; i<len; i++){...}

Теперь я знаю, что str.length() - это операция с постоянным временем в Java, потому что длина сохраняется как поле в классе String. Но опять же, строки неотменяемы в Java. Однако я не уверен в строках JS. Является ли str.length гарантированным постоянное время в JS? Не удалось найти это в любом месте в Интернете.

Ответ 1

Строки также неизменяемы в JavaScript. Свойству length не нужно вычислять каждый раз, когда к нему обращаются.

Я создал jsperf benchmark для просмотра здесь.

Вы заметите, что скорости одинаковы.

Ответ 2

Является ли str.length гарантированное постоянное время в JS?

Нет, на самом деле в JavaScript нет гарантии исполнения или сложности.

Однако да, можно ожидать, что он будет доступен в постоянное время без вычисления динамической линейной временной длины при доступе. Спецификация ECMAScript также описывает String .length свойство как неизменяемую и что она инициализируется при построении строки.

Ответ 3

Длина - это свойство экземпляра и постоянное время

Он должен реализовывать строку с заданной длиной, которая представляется как непрерывный массив jschars с нулевым завершением. Он делает это, явно сохраняя длину и указатель на массив с нулевым завершением

Явно сохранен индикатор здесь, что это постоянное время.

Прочитайте Как реализуются строки в SpiderMonkey для получения дополнительной информации о том, как Firefox реализует строки.

Ответ 4

Вопрос, как представляется, был хорошо ответил, но вот еще 2 ¢, которые могут быть полезны.

Использование string.length может привести к неожиданному поведению для циклов, если строка будет перезаписана чем-то с другой длиной внутри цикла, например:

var k = "abcabcabc";
for(var i=0; i<k.length; i++){
  k=k.slice(0,-1);
  console.log(k);
}

Будут записывать "abcabcab", "abcabca",..., "abca", а затем останавливаться, потому что длина изменяется.

Конечно, это может быть преднамеренным, и в этом случае пойти на это (хотя, возможно, вы должны использовать цикл while).

Ответ 5

На любом языке, который имеет неотъемлемые строки, будь то Java, JavaScript, С# или другие, это будет очень плохой практикой со стороны создателей языка НЕ ​​предоставлять операцию "длина времени" для строки.
Поскольку строка неизменна, ее длина не может изменяться, поэтому требуется только сохранить длину строки при создании в некотором поле внутри объекта строки и вернуть ее при вызове к методу "длина" /метод.

Ответ 6

W3Schools рекомендует, что вы используете это:

l = arr.length;
for (i = 0; i < l; i++) {..}

вместо этого:

for (i = 0; i < arr.length; i++) {...}

Утверждение, что:

Плохой код обращается к свойству length массива каждый раз, когда цикл повторяется.

Лучший код обращается к свойству length вне цикла и заставляет цикл работать быстрее.


Лучше ли хранить часто используемые значения в локальной переменной?

Поскольку w3schools является злым, позвольте мне привести цитату из другого источника (Написание эффективного JavaScript - Николас К. Закас).

... Важным уроком, который следует извлечь из этой информации, является всегда сохранение часто используемых значений в локальной переменной. Рассмотрим следующий код:

function process(data){
    if (data.count > 0){
        for (var i=0; i < data.count; i++){
            processData(data.item[i]);
        }
    }
}

... Функция будет работать быстрее, если это значение сохраняется в локальной переменной а затем доступ оттуда:

function process(data){
    var count = data.count;
    if (count > 0){
        for (var i=0; i < count; i++){

            processData(data.item[i]);
        }
    }
}

Почему доступ к свойствам медленнее, чем доступ к переменным экземпляра?

От здесь:

Большинство движков JavaScript используют структуру данных, подобную словарю, в качестве хранилища для свойств объекта - для каждого доступа к свойствам требуется динамический поиск для разрешения местоположения свойства в памяти. Этот подход делает доступ к свойствам в JavaScript, как правило, намного медленнее, чем доступ к переменным экземпляра на языках программирования, таких как Java и Smalltalk.


Почему производительность бенчмаркинга не показывает различий?

В целом некоторые (или большинство) JavaScript-движков используют методы оптимизации для улучшения времени доступа к ресурсу, например этот V8.

Кроме того, строковые объекты JavaScript могут иметь различный характер, поскольку вы не можете динамически добавлять их свойства. (что делает динамический поиск ненужным.. Думаю)


Заключение

Для string.length используйте любой из двух фрагментов кода. Но для других типов объектов или свойств, которые выполняют вычисления, вам нужно сначала проверить производительность вашего кода (или просто сохранить значение в локальной переменной).