Свойства JavaScript рассчитываются при каждом вызове? - PullRequest
9 голосов
/ 03 октября 2008

Поскольку length является свойством JavaScript, имеет ли значение, использую ли я

for( var i = 0; i < myArray.length; i++ )

OR

var myArrayLength = myArray.length;
for( var i = 0; i < myArrayLength ; i++ )

Ответы [ 8 ]

9 голосов
/ 03 октября 2008
for(var i = 0, iLen = myArray.length; i < iLen; i++)

См. http://blogs.oracle.com/greimer/resource/loop-test.html для тестов различных конструкций цикла Javascript.

2 голосов
/ 06 октября 2008

Я думаю, что ответ на вопрос вашего вопроса: да, свойство array.length пересчитывается на каждой итерации цикла, если вы изменяете массив в цикле. Например, следующий код:

var arr = [1,2,3];
for(var i = 0; i < arr.length; i++){
  console.debug("i = " + i);
  console.debug("indexed value = " + arr[i])
  arr.pop();
}

выведет:

i = 0
indexed value = 1
i = 1
indexed value = 2

тогда как этот код:

var arr = [1,2,3];
var l = arr.length;
for(var i = 0; i < l; i++){
  console.debug("i = " + i);
  console.debug("indexed value = " + arr[i])
  arr.pop();
}

выведет:

i = 0
indexed value = 1
i = 1
indexed value = 2
i = 2
indexed value = undefined

-J

2 голосов
/ 03 октября 2008

Если myArray является массивом javascript, вам не нужно беспокоиться об этом, это просто свойство поиска объекта, но также и использование переменной.

Если длина OTH - это свойство, предоставляемое объектом коллекции, предоставляемым DOM браузера (особенно IE), то это может быть удивительно дорого. Следовательно, при перечислении такой коллекции, предоставленной DOM, я склонен использовать: -

for (var i = 0, length = col.length; i < length; i++)

но для массивов я не беспокоюсь об этом.

1 голос
/ 04 октября 2008

Свойство length не вычисляется при каждом вызове, но последняя версия будет быстрее, поскольку вы кэшируете поиск свойства. Даже при использовании самых современных реализаций JS (V8, TraceMonkey, SquirrelFish Extreme), в которых используется расширенное (например, SmallTalk era;)), кэширование поиска свойства по крайней мере на одну дополнительную условную ветвь больше, чем ваша вторая версия.

Array.length не постоянна, так как массивы JS являются изменяемыми, поэтому push, pop, array[array.length]=0, etc может изменить его.

Существуют и другие концепции, такие как DOM NodeList s, которые вы получаете от вызовов типа document.getElementsBySelector, которые, как ожидается, будут активными, и в этом случае длина может быть пересчитана при итерации. Но затем, если длина будет пересчитана, есть большая вероятность, что она также действительно изменится, поэтому ручное кэширование вывода может быть недопустимым.

1 голос
/ 03 октября 2008

Нет. Он не пересчитывается по вызову. Он пересчитывается в соответствии с требованиями класса Array.

Это изменится, если вы используете push , pop , shift , unshift , concat , сращивание и т. Д. В противном случае это просто число - один и тот же экземпляр каждый раз, когда вы вызываете его значение.

Но, если вы не переопределите его явно ( array.length = 0 ), оно будет точным при каждом вызове.

0 голосов
/ 06 октября 2008

Если вы когда-либо предполагали, что оно может измениться во время цикла, то, конечно, его следует проверять для каждого цикла ...

- иначе, очевидно, глупо просить объект несколько раз, как это было бы, если бы вы поместили его в свойство оценки оператора if ...

if(i=0, iMax=object.length; iMax>i; i++)

- только в особых случаях вы должны подумать о том, чтобы поступить иначе! -)

0 голосов
/ 04 октября 2008

Согласно спецификации ECMAScript , он просто сообщает , как должно быть рассчитано свойство "length", но не говорит , когда . Я думаю, что это может зависеть от реализации.

Если бы я реализовал это, я бы сделал, как указал Джонатан , но в случае свойства "length" из объектов Array.

0 голосов
/ 03 октября 2008

Хотя вторая форма может быть быстрее:

function p(f) { var d1=new Date(); for(var i=0;i<20;i++) f(); print(new Date()-d1) }
p(function(){for(var i=0;i<1000000; i++) ;})
p(function(){var a = new Array(1000000); for(var i=0;i<a.length; i++) ;})
> 823
> 1283

.. это не должно иметь никакого значения в любом случае без края.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...