Переприсвоение переменной
Доброго,
Встречается такой код: function foo(arg1) { arg1 = arg1 || 'что-то опциональное'; ... } Все работает отлично, но вопрос. Будет ли такое переприсвоение иметь негативные последствия, допустим, утечки памяти? Вообще, будет ли заново выделяться память под ту же самую переменную? Или все зашибись, не надо париться? Спасибо. |
Цитата:
|
Михаил Хе,
А вот такая ситуация вас не волнует? for (var i = 0; i < 1000; i++) { ... } Счетчику переприсваивается значение:-E Переприсвоение ничем не отличается от обычного присвоения - значение присваивается одной и той же переменной |
Цитата:
Меня насторожило, что именно происходит при переприсвоении переменной обратно на себя, может ли движок правильно "ничего не сделать, не париться попусту". |
Цитата:
Все это "одно и то же дело". Вот тебе еще одно... var s=0; var val=10; s=s+val; И такого сплошь и рядом! :D Если бы твои опасения были не напрасны - в мире JS наступил бы крах! :cray: |
Михаил Хе,
Цитата:
Кому и что оно должно? |
Давайте без эмоций, я понимаю, что дело плевое и вроде как проблем нет, но мой пример кардинально отличается от этого:
var s=0; var val=10; s=s+val; и от этого i = i + 1; В этих двух примерах движок JS реально делает действия по изменению состояния переменных. В логическом случае с var1 = var1; движок не должен ничего делать. Я правильно разъяснил? Давайте вникать. |
Михаил Хе,
Цитата:
|
Кстати, в вашем начальном примере возможно даже изменение типа переменной
function foo(arg1) { arg1 = arg1 || 'что-то опциональное'; alert(arg1); } foo(0); foo(1); foo('что-то'); |
Цитата:
Если arg1 не пустое, до операции со строкой дело не дойдет, остается arg1 = arg1. здесь память тоже не выделяется, она уже выделена на стеке, arg1 обычная стековая переменная, просто записываются данные в ячейку памяти. |
Цитата:
Пример arg1 = arg1 || ''; аналогичный, при условии, что arg1 истина - тоже ничего не должно происходить (по факту состояния среды всего и всея движка). |
Вероятно после оптимизации строка "arg1 = arg1" вообще будет удалена, т.к. смысла в ней нет.
|
Цитата:
в случае "arg1 = arg1 || '...'", возможно, компилятор переосмыслит её как if (!arg1) { arg1 = '...'; } |
Цитата:
|
Цитата:
function foo(arg){ ...; return arg;} var var1 = {}; var1 = foo(var1); |
Цитата:
|
Цитата:
|
Что за гадания на кофейной гуще. Все исходники в открытом доступе.
https://github.com/v8/v8/tree/f165df...rc/interpreter Код не сложный и ни сказать что бы слишком большой. вполне по силам среднему разработчику. Первое что делает интерпретатор строит лексическое дерево и на основании него генерирует байткод. Никаких оптимизаций в этот момент не производится. Байткод сразу же готов к работе в своей вм. Лексическое дерево разбивается на области видимости. Константы и логика в виде байт кода хранится отдельно а переменные параметры возвращаемое значение ссылки на другие области видимости хранятся в отдельной таблице ключ значение дальше в куче. смещение на эту кучу передается блоку кода при вызове ( Именно по этому работает такое понятие как поднятие переменных т.к. на момент исполнения блока кода имя переменной уже есть в таблице ключ значение для этого блока кода.). Данные хранятся отдельно от блока кода для того что бы работали такие вещи как замыкания и рекурсия. т.е. под каждое имя в данной области видимости есть только одно место в таблице ключ значение (хеш таблица). При интерпретации в виртуальной машине операторы строки выполняются согласно своим приоритетам каждый раз когда встречается идентификатор "arg1" идет обращение к одному и тому же месту в таблице. Если блок кода (функция) вызывается часто или выполняется долго (интерпретатор считает время исполнения) то этот блок передается оптимизатору а там все сложно =). |
Часовой пояс GMT +3, время: 22:39. |