JS Variable Scope Lookup vs Allocation

Если я применяю функцию к массиву javascript, т.е.

var a = [1,2,3,4];
var x;

a.forEach(function(val) {
    x = val + 1;
    // do some stuff with x        
});

Что лучше: оставить объявление переменной во внешней области или поместить объявление внутри функции? т.е.

var a = [1,2,3,4];

a.forEach(function(val) {
    var x = val + 1;
    // do some stuff with x
});

Я не знаю, стоит ли выделение памяти для x дороже, чем процесс поиска переменных.

Обычно это не повод для беспокойства с точки зрения памяти.

H.B. 24.03.2018 16:48

Переменная, объявленная снаружи обратного вызова, будет доступна еще одним поиском по сравнению с объявленной внутри. Однако, если ваш массив не очень большой, я думаю, это не будет иметь никакого значения.

Mohammad Usman 24.03.2018 16:50

Как говорят другие; обычно не стоит беспокоиться о памяти. Однако в вашем первом примере xбудут будет доступен после вызова функции, тогда как x во втором примере ограничен только этой функцией.

Exfridos 24.03.2018 16:51

Кроме того, JS-движок в любом случае много оптимизирует для подобных вещей.

H.B. 24.03.2018 16:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
196
4

Ответы 4

Если вам не нужна переменная вне функции обратного вызова forEach, поместите ее внутрь. Так просто чище. Память не проблема.

Лучше положить в петлю. Разницы в производительности нет. Однако правильное использование осциллографа - хорошая отправная точка для обнаружения ошибок:

  var something = 5;

  a.forEach(el => something = el);

  console.info(something); // what is something? Why is it set?

What I do not know is if the memory allocation for x is more expensive than the variable lookup process

По-разному. Это зависит от точного кода, размера массива, частоты запуска кода, количества областей между кодом, обращающимся к переменной, и областью, в которой объявлена ​​переменная, какие оптимизации движок JavaScript, на котором выполняется код бег делает и т. д.

Так: напишите самый ясный и простой код, который вы можете, и если вы столкнетесь с проблемой производительности, связанной с этим кодом, профиль изменяется, чтобы увидеть, как ее решить. Все остальное - преждевременная оптимизация и пустая трата вашего времени.

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

Спасибо. Я действительно просто спрашивал из любопытства. Судя по ответам, stackoverflow не подходил для этого.

gph 24.03.2018 16:57

@gph: Насколько я знаю, вопросы теории здесь прекрасны. Но да, когда люди видят то, что они считают преждевременной микрооптимизацией, прагматичные шляпы остаются в силе. :-) В любом случае, FWIW, я был бы очень удивлен, если бы объявление этого в обратном вызове было медленнее, чем объявление его снаружи.

T.J. Crowder 24.03.2018 17:02

@ T.J.Crowder, конечно, медленнее объявляет (раз п) внутри cb с gc, чем снаружи, но я бы сделал это внутри, если не требуется никакого использования снаружи.

Nina Scholz 24.03.2018 17:09

@NinaScholz: сборщик мусора не требуется (кроме извлечения стека, что происходит в любом случае), x будет переменной стека на любом современном движке (если только мы не предположим, что закрытие, созданное обратным вызовом, сохраняется после его выхода, и нет никаких указаний на это в коде OP). Акт выхода из обратного вызова восстанавливает его, когда вы выталкиваете стек.

T.J. Crowder 24.03.2018 17:29
Этот jsPerf предполагает, что обратный вызов действительно (немного) быстрее.
T.J. Crowder 24.03.2018 17:41

Фактически, это изменение контролирует два параметра: область действия и инициирование. Область действия: если вам нужно использовать эту переменную вне цикла, поэтому вам нужно объявить ее вне цикла, иначе вы можете вставить ее, и каждая итерация, и область действия будет объявляться, это, вероятно, экономит память за пределами области. Инициирование: в больших программах инициация может быть критической, каждый раз, когда происходит цикл, вам нужно объявлять var и время, которое оно тратит ...

Другие вопросы по теме