Javascript - это язык для сборки мусора. Это означает, что объект или содержимое переменной в Javascript НЕ автоматически освобождается, когда оно выходит из области видимости в функции. Вместо этого объект живет до тех пор, пока не будет больше активного кода, который сможет его достичь.
Итак, в вашей функции вы устанавливаете обработчик событий для объекта connection
. Пока где-то есть активный код, который все еще имеет ссылку на этот объект соединения, Javascript не будет собирать мусор для этого объекта.
В данном конкретном случае объект connection
представляет собой действующее TCP-соединение с другим хостом, и за этим TCP-соединением есть и код Javascript, и собственный код, который по-прежнему имеет ссылку на объект соединения и может вызывать события на нем. Движок Javascript знает, что этот код все еще имеет ссылку на этот объект, поэтому он не будет собирать мусор. И, разумеется, каждый раз, когда новый пакет поступает в соединение webSocket, он вызывает ваш обработчик onMessage.
Способ сделать этот объект подключения пригодным для сбора мусора - закрыть соединение. Это заставит код webSocket и собственный код за ним очистить любые ссылки, которые он имеет на объект соединения, и тогда он будет иметь право на сборку мусора.
В Javascript никогда не следует думать, что локальные переменные функции имеют время жизни, строго связанное с возвращением функции. Вскоре вы обнаружите, что (особенно из-за асинхронного характера многих операций в Javascript), что локальные переменные в функции остаются живыми еще долго после ее возврата, и это оказывается очень и очень полезным.
Ментальная модель, которую я использую (которая может или не может быть именно так, как она реализована), которая помогает мне понять все это, состоит в том, чтобы никогда не думать о локальных переменных в функции как о размещенных в кадре стека. Вместо этого думайте о них как о динамически размещаемых в куче. Они могут жить в этой куче столько времени, сколько необходимо, в том числе и после того, как функция уже вернулась. Сборщик мусора освободит их, если их не использует ни один код или они могут больше не использоваться.
Из-за асинхронных обратных вызовов (как в вашем примере) такой обратный вызов может легко заставить локальные переменные оставаться живыми еще долго после того, как содержащая функция уже вернулась.
переменная соединения является локальной, поэтому ссылка на объект WebSocket выходит из области видимости, когда ready () выходит
Вещи в области действия функции не освобождаются автоматически при возврате содержащей функции. Они не размещаются в стеке, как в C / C ++. Они будут собирать мусор и будут освобождены, когда они больше не будут использоваться.
Я ожидаю, что соединение должно прерваться вместе с обратным вызовом, но каким-то образом я все еще могу получить обратные вызовы connection.onmessage
см. Выше. Локальные переменные в Javascript могут жить долго после того, как их функция хоста вернется.
Насколько я понимаю, это связано не с областями видимости JavaScript, а с тем, как внутренние соединения WebSocket организованы.
Это не относится конкретно к webSocket. Как описано выше, это происходит из-за сборки мусора в Javascript. Код, который управляет (все еще живым) соединением webSocket, имеет прямую ссылку на объект connection
и таким образом предотвращает его сборку мусора. Чтобы завершить эту действующую ссылку, вы должны закрыть соединение webSocket, а затем код, управляющий соединением webSocket, очистит его ссылки на объект соединения, и тогда он будет пригоден для сборки мусора.