Выделяет ли 'var' новую память при повторном доступе или перезаписывает ее?

function Foo(){
  var someObj = {
    s: 'string'
  }

  console.info(someObj.s);
}

Foo(); // first call
Foo(); // second call

Будет ли память, на которую указывает someObj, будет перезаписана или будет выделена новая? Если будет выделена новая память, что произойдет с someObj, созданным при первом вызове, сотрет ли его сборщик мусора? И должен ли я сделать определение someObj вне функции, чтобы уменьшить количество операций с памятью?

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

Code Maniac 27.05.2019 13:12
Поведение ключевого слова "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) для оценки ваших знаний,...
3
1
46
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

При каждом вызове someObj будет создаваться новый Foo. Вы можете проверить это, вернув объект и посмотрев, равен ли новый:

function Foo(){
  var someObj = {
    s: 'string'
  };
  return someObj;
}
console.info(Foo() === Foo());

Они не совпадают — место в памяти, на которое указывает первый someObj, не совпадает с местом в памяти, на которое указывает второй someObj. Если вы постоянно вызываете Foo, не оставляя времени для запуска сборщика мусора, в конечном итоге у вас закончится память.

Если объект не возвращается, то после запуска Foo ничто другое не может ссылаться на someObj, поэтому вскоре он будет подвергнут сборке мусора.

Если вы хотите предотвратить создание нескольких someObj, да, не стесняйтесь определять someObj вне Foo.

Если вы хотите, чтобы на someObj можно было ссылаться только внутри Foo, а также создавать только один такой объект, тогда превратите Foo в IIFE:

const Foo = (() => {
  var someObj = {
    s: 'string'
  };
  return () => {
    console.info(someObj.s);
  };
})();

Foo();
If you want someObj to only be referenceable inside of Foo while also creating only one such object, then turn Foo into an IIFE а можно подробнее эту строчку? я не думаю, что мы можем получить доступ к someObj вне функции даже в коде OP
Code Maniac 27.05.2019 13:19

Верно, к нему нельзя получить доступ извне, но он все равно создается ровно один раз, когда запускается IIFE. Он также может быть возвращен из внутренней функции, если вы хотите, но для чего-то постоянного, что не имеет большого смысла в большинстве ситуаций IMO

CertainPerformance 27.05.2019 13:21

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

Но:

Will the memory where the someObj points to are overwritten or will a new one be allocated?

Я говорю, что он выделяется каждый раз, когда вызывается функция. Или, другими словами, вы можете все время рассматривать его как новую переменную.

what happens with someObj created at first call, will garbage collector erase it

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

And should I make a definition of someObj outside the function to reduce the number of memory operations?

Из моих знаний о V8 и подобных, если тип всегда один и тот же, есть некоторые встроенные методы, которые сделают эту оптимизацию.

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

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

В качестве примечания. Код в первую очередь для других людей. Он должен быть удобочитаемым для них в первую очередь.

Эта функция вызывается около 80 000 раз, а объект больше, поэтому я так беспокоюсь о таких вещах.

Vlad Ross 27.05.2019 13:21

Я бы не стал выводить эту переменную из области действия функций, если бы не был на 100% уверен, что это не приведет к условиям гонки со странной асинхронностью. Но сделайте свои тесты и посмотрите, даст ли это вам какие-либо преимущества.

sznowicki 27.05.2019 13:23

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