Js удалить переменную из памяти
The JavaScript delete operator removes a property from an object; if no more references to the same property are held, it is eventually released automatically.
Try it
Syntax
Where expression should evaluate to a property reference, e.g.:
Parameters
The name of an object, or an expression evaluating to an object.
The property to delete.
Return value
true for all cases except when the property is an own non-configurable property, in which case, false is returned in non-strict mode.
Exceptions
Throws TypeError in strict mode if the property is an own non-configurable property.
Description
Unlike what common belief suggests (perhaps due to other programming languages like delete in C++), the delete operator has nothing to do with directly freeing memory. Memory management is done indirectly via breaking references. See the memory management page for more details.
The delete operator removes a given property from an object. On successful deletion, it will return true , else false will be returned.
However, it is important to consider the following scenarios:
- If the property which you are trying to delete does not exist, delete will not have any effect and will return true .
- If a property with the same name exists on the object's prototype chain, then, after deletion, the object will use the property from the prototype chain (in other words, delete only has an effect on own properties).
- Any property declared with var cannot be deleted from the global scope or from a function's scope.
- As such, delete cannot delete any functions in the global scope (whether this is part from a function definition or a function expression).
- Functions which are part of an object (apart from the global scope) can be deleted with delete .
The following snippet gives a simple example:
Non-configurable properties
When a property is marked as non-configurable, delete won't have any effect, and will return false . In strict mode this will raise a TypeError .
var , let , and const create non-configurable properties that cannot be deleted with the delete operator:
In strict mode, this would have raised an exception.
Strict vs. non-strict mode
When in strict mode, if delete is used on a direct reference to a variable, a function argument or a function name, it will throw a SyntaxError . Therefore, to avoid syntax errors in strict mode, you must use the delete operator in the form of delete object.property or delete object['property'] .
Cross-browser notes
Although ECMAScript makes iteration order of objects implementation-dependent, it may appear that all major browsers support an iteration order based on the earliest added property coming first (at least for properties not on the prototype). However, in the case of Internet Explorer, when one uses delete on a property, some confusing behavior results, preventing other browsers from using simple objects like object literals as ordered associative arrays. In Explorer, while the property value is indeed set to undefined , if one later adds back a property with the same name, the property will be iterated in its old position--not at the end of the iteration sequence as one might expect after having deleted the property and then added it back.
If you want to use an ordered associative array in a cross-browser environment, use a Map object if available, or simulate this structure with two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc.
Examples
delete and the prototype chain
In the following example, we delete an own property of an object while a property with the same name is available on the prototype chain:
Deleting array elements
When you delete an array element, the array length is not affected. This holds even if you delete the last element of the array.
When the delete operator removes an array element, that element is no longer in the array. In the following example, trees[3] is removed with delete .
If you want an array element to exist but have an undefined value, use the undefined value instead of the delete operator. In the following example, trees[3] is assigned the value undefined , but the array element still exists:
If instead, you want to remove an array element by changing the contents of the array, use the splice() method. In the following example, trees[3] is removed from the array completely using splice() :
Удаляет объект, свойство объекта или элемент массива по указанному индексу.
Значением expression должна являтся ссылка на удаляемое свойство, например:
Если expression не приводится к свойству, оператор delete не делает ничего.
При успешном выполнении оператор delete удаляет свойство из объекта.
При этом delete не меняет прототип объекта, даже если там есть свойство, совпадающее по названию с удаляемым.
Некоторые свойства объектов не могут быть удалены. В спецификации такие свойства обозначены флагом DontDelete .
Можно удалить переменные, объявленные глобально без var , но нельзя - объявленные через var .
Оператор delete возвращает false только если свойство существует, но не может быть удалено, и true - в любых других случаях.
Вы не можете удалить свойство из объекта, которое он унаследовал от прототипа (хотя вы можете удалить его напрямую из прототипа).
При удалении элементов массива, его длина не меняется. Даже если вы удалите последний элемент: delete a[a.length-1] - его длина останется той же.
При этом элемент исчезнет из массива:
Если вы хотите, чтобы элемент остался в массиве, но стал undefined - просто приравняйте его к undefined :
См. также
А можно ли как-то удалить класс, например
function Foo()<>
delete Foo;Почему-то использование window.Foo = null; не очищает память.
в javascripte нет классов! Это не класс а объект, а конкретнее - функция-конструктор. Память очищает сборщик мусора, который решает удалять ли данные по каким-то своим магическим алгоритмам.
Как написано в коменте выше, это не класс, а функция. Функцию можно удалить так же, как и любой другой объект, если создавать ее динамически и присваивать в глобальную переменную. Вот так, например, можно:
Foo = function()<>;
delete Foo;Написаный вами вариант эквивалентен следующему:
var Foo = function()<>;
delete Foo;А как написано в статье, переменные, объявленные через var, удалять нельзя.
Оператор delete удаляет не сам объект, а ссылку(указатель) на объект.
ПримерТоесть из объекта а мы удалили ссылку на объект [1,2,3], но сам объект из памяти не удалился, т.к. на него указывает другой указатель. Объект удалится только по прихоти и решению GC.
к сожалению даже узнать, удалил ли мусоросборщик этот объект, не получиться:
В браузерах Chrome Версия 19.0.1084.56 и Firefox 13.0 удаляется:
локальные элементы в текущем closure удалять нельзя, видимо, GC итак их удалит при выходе из closure
А вот Google Closure при проверке кода на валидность ругается на удаление результата функции, т.е.
delete foo()
хотя по стандарту операция валиднаУ меня есть глобальная переменная в JavaScript (на самом деле это window свойство, но я не думаю, что это имеет значение), которое уже было заполнено предыдущим скриптом, но я не хочу, чтобы другой скрипт запускался позже, чтобы увидеть его значение или что он был даже определены.
Я поставил, some_var = undefined и это работает с целью тестирования, typeof some_var == "undefined" но я действительно не думаю, что это правильный путь.
delete Оператор удаляет свойство из объекта. Он не может удалить переменную. Таким образом, ответ на вопрос зависит от того, как определяется глобальная переменная или свойство.
(1) Если он создан с помощью var , он не может быть удален.
(2) Если он создан без var , его можно удалить.
Техническое объяснение
1. Использование var
В этом случае ссылка g_a создается в том, что спецификация ECMAScript называет « VariableEnvironment », которая присоединена к текущей области - это может быть контекст выполнения функции в случае использования var внутри функции (хотя это может быть немного сложнее если учитывать let ) или в случае «глобального» кода VariableEnvironment присоединяется к глобальному объекту (часто window ).
Ссылки в VariableEnvironment обычно не удаляются - процесс, подробно описанный в ECMAScript 10.5, объясняет это подробно, но достаточно сказать, что если ваш код не выполняется в eval контексте (который используется большинством браузерных консолей разработки), то переменные, объявленные с var помощью, не могут быть удаленным.
2. Без использования var
При попытке присвоить значение имени без использования var ключевого слова Javascript пытается найти именованную ссылку в том, что спецификация ECMAScript называет « LexicalEnvironment », и основное отличие заключается в том, что элементы LexicalEvironment являются вложенными - то есть LexicalEnvironment имеет родителя ( то, что спецификация ECMAScript называет «ссылкой на внешнюю среду»), и когда Javscript не удается найти ссылку в LexicalEenvironment , он ищет в родительской среде LexicalEnvironment (как подробно описано в 10.3.1 и 10.2.2.1 ). Верхний уровень LexicalEnvironment - это « глобальная среда»", и это связано с глобальным объектом в том смысле, что его ссылки являются свойствами глобального объекта. Поэтому, если вы попытаетесь получить доступ к имени, которое не было объявлено с использованием var ключевого слова в текущей области или каких-либо внешних областях, Javascript в конечном итоге получит свойство от window объекта , чтобы служить этой ссылке. Как мы узнали ранее, свойства на объекты могут быть удалены.
Важно помнить, что var объявления «подняты», т. Е. Всегда считается, что они произошли в начале области действия, в которой они находятся, - но не при инициализации значения, которое может быть выполнено в var операторе, - который остается там, где он находится. , Таким образом, в следующем коде a это ссылка из VariableEnvironment, а не window свойство, и его значение будет 10 в конце кода:
То, что вы сказали, является распространенным заблуждением, но на самом деле неверно - в Javascript нет «глобальных переменных». Переменные, определенные без явной области видимости (например, использование var вне функции), являются свойствами "глобального объекта", который есть в веб-браузерах window . Так что - var a = 1; delete window.a; console.log(a); удалит переменную и заставит последнюю строку выдать ошибку ссылки.
Я использую Google Chrome v36. Я тестировал в других браузерах. Похоже, что это не соответствует кросс-браузеров. Chrome и Opera отображали 1, в то время как Firefox, Safari и IE 11 на моем компьютере выдавали ошибку.
@KlaiderKlai да. Переменные области действия функции создаются и уничтожаются каждый раз, когда функция выполняется. Вероятно, закрытие является исключением.
Ответ @ scunlife сработает, но технически это должно быть
Предполагается, что delete не используется, если цель не является свойством объекта. например,
Но поскольку глобальные переменные на самом деле являются членами объекта window, это работает.
Когда задействованы цепочки прототипов, использование delete становится более сложным, поскольку оно удаляет только свойство из целевого объекта, а не прототип. например,
Так что будь осторожен.
РЕДАКТИРОВАТЬ: Мой ответ несколько неточный (см. «Заблуждения» в конце). Ссылка объясняет все кровавые подробности, но в итоге можно сказать, что между браузерами могут быть большие различия в зависимости от объекта, из которого вы удаляете. delete object.someProp как правило, должны быть в безопасности, пока object !== window . Я все еще не использовал бы это, чтобы удалить переменные, объявленные с, var хотя вы можете при правильных обстоятельствах.
Что касается последнего предложения пересмотренного ответа, единственное обстоятельство, при котором вы можете удалить переменные, объявленные с, var - это когда переменная была объявлена с eval .
@ AndersonGreen - глобальные переменные в декальтере создаются с флагом DontDelete, поэтому их нельзя удалить. Этот код ведет себя точно так, как ожидалось.
Если вы неявно объявляете переменную без var , правильным способом будет использование delete foo .
Однако после его удаления, если вы попытаетесь использовать это в такой операции, как добавление, ReferenceError будет брошено, потому что вы не можете добавить строку в необъявленный, неопределенный идентификатор. Пример:
В некоторых ситуациях может быть безопаснее присвоить ему значение false, null или undefined, чтобы оно было объявлено и не выдавало этот тип ошибки.
Обратите внимание , что в ECMAScript null , false , undefined , 0 , NaN , или '' бы все вычисляться false . Просто убедитесь, что вы не используете !== оператор, а вместо этого != при проверке типа для логических значений, и вы не хотите, чтобы проверка идентичности (так null будет == false и false == undefined ).
Также обратите внимание, что delete ссылки не «удаляются», а только свойства непосредственно на объекте, например:
Если вы объявили переменную, var вы не можете ее удалить:
Также вы не можете удалить некоторые предопределенные свойства, такие как Math.PI :
Есть некоторые странные исключения, delete как и в случае с любым другим языком, если вы достаточно внимательны, вы должны прочитать:
Спасибо за полный ответ со всеми деталями. Я пометил это для этого, но я принял ответ Ноя, потому что я считаю, что для простого вопроса важнее краткость, чем завершение. Еще раз - спасибо за отличную работу, которую вы проделали с этим ответом.
Каков наилучший способ удалить свойство, regex чтобы закончить с новым myObject следующим образом?
@EscapeNetscape Это вопрос о поведении, поэтому тест отображает неправильную картину. Конечно, delete это будет самый медленный вариант, поскольку это фактическая операция, а не две другие, которые являются просто назначениями. Но суть дела в том , что назначение свойства null или на undefined самом деле не удалить свойство из объекта, но вместо этого устанавливает , что собственность на равную определенную величину постоянной. (Ниже приведены причины, по которым это существенно отличается.)
Результатом одного из наблюдений по ссылке «понимание удаления» выше является то, что, поскольку вы не можете обязательно удалить переменную, а только свойства объекта, вы, следовательно, не можете удалить свойство объекта «по ссылке» - var value = obj [ 'проп']; удалить значение // не работает
Так что на самом деле это не удалить? Это просто становится неопределенным, но ключ все еще существует? Я что-то пропустил?
@ChristopherPfohl работает на меня. Как я уже сказал, на самом деле это довольно глубоко, поэтому подвести итог немного сложно. Основной ответ в ответе выше достаточен почти для всех случаев, в блоге рассматриваются еще некоторые крайние случаи и причины, по которым эти случаи существуют.
Объекты в JavaScript могут рассматриваться как карты между ключами и значениями. delete Оператор используется , чтобы удалить эти ключи, более широко известные как свойства объекта, по одному за раз.
delete Оператор непосредственно не свободной памяти, и оно отличается от простого присвоения значения null или undefined к свойству, в том , что свойство само по себе удаляется из объекта. Обратите внимание, что если значением удаленного свойства был ссылочный тип (объект), а другая часть вашей программы по-прежнему содержит ссылку на этот объект, то этот объект, разумеется, не будет собирать мусор, пока все ссылки на него не будут иметь исчез.
delete будет работать только со свойствами, дескриптор которых помечает их как настраиваемые.
свойство, назначенное неопределенному, все еще является свойством объекта, поэтому оно не будет удалено GC, если вы не прочитали последний абзац.
Я был неправ, касаясь темы GC здесь. Оба метода имеют одинаковый результат для GC: они удаляют значение, связанное с ключом. Если это значение было последней ссылкой на какой-либо другой объект, этот объект был бы очищен.
свойство, назначенное неопределенному, все еще является свойством объекта, поэтому оно не будет удалено GC . GC ничего не управляет свойствами. Он собирает и удаляет значения. Пока ничто больше не ссылается на значение (объект, строку и т. Д.), GC действительно удаляет его из памяти.
Кстати, это двойная проблема, чтобы проверить, существует ли свойство в объекте Javascript. Использование в операторе надежно, но медленно. Проверьте, не является ли свойство неопределенным, «это не правильный ответ», но это намного быстрее. чек
Этот ответ по-прежнему актуален? jsperf в настоящее время не работает, но этот тест, похоже, указывает на то, что разница в скорости составляет всего 25%, что нигде не близко к «~ 100 раз медленнее» в этом ответе.
Это работает в Firefox и Internet Explorer, и я думаю, что это работает во всех остальных.
delete Оператор используется для удаления свойств из объектов.
delete в JavaScript функция отличается от функции ключевого слова в C и C ++: он не освобождает память напрямую. Вместо этого его единственной целью является удаление свойств из объектов.
Для массивов удаление свойства, соответствующего индексу, создает разреженный массив (т. Е. Массив с «дырой» в нем). Большинство браузеров представляют эти отсутствующие индексы как «пустые».
Обратите внимание, что delete не перемещается array[3] в array[2] .
Различные встроенные функции в JavaScript по-разному обрабатывают разреженные массивы.
for. in пропустит пустой индекс полностью.
Традиционный for цикл возвращает undefined значение в индексе.
Любой использующий метод Symbol.iterator вернёт undefined значение в индексе.
forEach , map И reduce просто пропустить отсутствующий индекс.
Этот подход не изменяет исходный объект, на который можно ссылаться в другом месте. Это может или не может быть проблемой, в зависимости от того, как она используется, но об этом следует помнить.
@wulftone nope, который разбивает массив и ничего не делает для удаления значения. Я действительно думаю, что лучший способ удаления из массива, в котором необходимо удалить определенные значения, - это использовать delete и создать функцию «Сборка мусора» для ее очистки.
Эта статья полна быка 1. Это не касается вопроса! 2. Это примерное злоупотребление языком и жалоба на то, что «это не работает!» 3. Не обвиняйте оператор удаления JavaScript в характерной ошибке Крокфорда, заключающейся в установке значения NULL для индекса пустого массива. Он не понимает значения нуля - он думает, что это ошибка. Ошибка является его собственной и единственной - в удаленном значении данного индекса массива нет нуля. В массиве нет «дыры» - это пустой индекс. Абсолютно законно и ожидаемо.
Старый вопрос, современный ответ. Используя деструктуризацию объектов, функцию ECMAScript 6 , это так просто, как:
Или с образцом вопросов:
Редактировать:
Чтобы переназначить одну и ту же переменную, используйте let :
Возможно, потому что цель состоит в том, чтобы удалить свойство из объекта, а не создать новое без свойства . хотя, ваше решение - мое любимое, так как я предпочитаю неизменный способ.
Добавление подчеркивания для удаления свойства засорять ваш проект :) Вместо того , чтобы он доступен , как regex вы могли бы также назначить его на какой - либо другой переменной, например _ , то , что используется в таких языках , как Go отбрасывать результат: const < regex: _, . newObject >= myObject; .
@PranayKumar Я надеялся, что этот синтаксис сработает; const < Js удалить переменную из памяти, . newObject >= myObject; но это не так, поэтому я не думаю, что это возможно с разрушением.
С объектами freeze() 'd и seal() ' d вы не можете просто delete создать свойство. Так что это отличная альтернатива. Хотя в большинстве случаев, вероятно, в любом случае не имеет смысла удалять свойство из замороженного / запечатанного объекта, учитывая, что весь смысл в том, чтобы дать определенные гарантии относительно ваших структур данных, которые этот шаблон будет подрывать. Для тех случаев, когда вам необходимо неразрушающим образом дублировать объект, но без некоторых его свойств, это идеально
Для тех, кто нуждается в этом .
Чтобы завершить ответ @Koen в этой теме, на случай, если вы захотите удалить динамическую переменную с использованием синтаксиса распространения, вы можете сделать это так:
* foo будет новой переменной со значением a ( равным 1).
РАСШИРЕННЫЙ ОТВЕТ 😇
Существует несколько распространенных способов удаления свойства из объекта.
У каждого есть свои плюсы и минусы ( посмотрите сравнение производительности ):Delete Operator
Readable и short, однако, это может быть не лучшим выбором, если вы работаете с большим количеством объектов, так как его производительность не оптимизирована.
Переназначение
Более чем в 2 раза быстрее, чем delete , однако свойствонеудаляется и может быть повторено.
Spread Operator
Этот ES6 оператор позволяет нам возвращать совершенно новый объект, исключая любые свойства, не изменяя существующий объект. Недостатком является то, что он имеет худшую производительность из вышеперечисленных и не рекомендуется использовать, когда вам нужно удалить много свойств одновременно.Я думаю, что синтаксис распространения / отдыха для литералов объектов был включен только в ES2018 (ES9), а не в ES6, хотя некоторые движки JS уже реализовали его.
Ссылка относится к ES6, где действительно был введен синтаксис распространения для массивов, но затем он продолжает предлагать нечто подобное для литералов объектов. Эта вторая часть была включена только в ES9, если я не ошибаюсь.
Другой альтернативой является использование библиотеки Underscore.js .
Обратите внимание , что _.pick() и _.omit() как вернуть копию объекта и не непосредственно изменять исходный объект. Присвоение результата исходному объекту должно помочь (не показано).
Ссылка: ссылка _.pick (объект, * ключи)
Возвращает копию объекта, отфильтрованного, чтобы иметь только значения для ключей из белого списка (или массива допустимых ключей).
Ссылка: ссылка _.omit (объект, * ключи)
Возвращает копию объекта, отфильтрованного для исключения ключей из черного списка (или массива ключей).
Для массивов _.filter() и _.reject() может быть использован аналогичным образом.
Имейте в виду, что если ключи вашего объекта являются числами, вам может понадобиться _.omit(collection, key.toString())
Хммммм . Подчеркивание в ~ 100 раз медленнее, чем delete obj[prop] в ~ 100 раз медленнее, чем obj[prop] = undefined .
Термин, который вы использовали в заголовке вашего вопроса Remove a property from a JavaScript object , может интерпретироваться по-разному. Один из них - удалить всю память и список ключей объекта, а другой - просто удалить его из вашего объекта. Как уже упоминалось в некоторых других ответах, delete ключевое слово является основной частью. Допустим, у вас есть ваш объект, как:
Если вы делаете:
Вы можете удалить этот конкретный ключ из ваших ключей объекта, например:
Тогда ключ вашего объекта Object.keys(myJSONObject) будет:
Но дело в том, что если вы заботитесь о памяти и хотите, чтобы весь объект был удален из памяти, рекомендуется установить его в null перед удалением ключа:
Другим важным моментом здесь является осторожность в отношении других ссылок на тот же объект. Например, если вы создаете переменную вроде:
Или добавьте его как новый указатель на другой объект, например:
Тогда, даже если вы удалите его из своего объекта myJSONObject , этот конкретный объект не будет удален из памяти, поскольку regex переменная myOtherObject["regex"] все еще имеет свои значения. Тогда как мы можем точно удалить объект из памяти?
Ответ будет состоять в том, чтобы удалить все ссылки, которые вы имеете в своем коде, указывающие на этот самый объект, а также не использовать var операторы для создания новых ссылок на этот объект . Этот последний пункт, касающийся var операторов, является одной из наиболее важных проблем, с которыми мы обычно сталкиваемся, поскольку использование var операторов будет препятствовать удалению созданного объекта.
Это означает, что в этом случае вы не сможете удалить этот объект, потому что вы создали regex переменную с помощью var оператора, и если вы это сделаете:
Результат будет false , что означает, что ваш оператор удаления не был выполнен, как вы ожидали. Но если вы ранее не создавали эту переменную и использовали только myOtherObject["regex"] свою последнюю существующую ссылку, вы могли бы сделать это, просто удалив ее следующим образом:
Другими словами, объект JavaScript уничтожается, как только в вашем коде не остается ссылки на этот объект.
Обновление: благодаря @AgentME:
Установка свойства в null перед его удалением ничего не делает (если объект не был запечатан Object.seal, и удаление завершилось неудачей. Обычно это не так, если вы специально не пытаетесь).
Чтобы получить больше информации о Object.seal : Object.seal ()
Вы ошибаетесь - только объекты передаются по ссылке в JavaScript, поэтому, если myJSONObject.regex значение является строкой и вы назначаете его какому-либо другому объекту, у другого объекта есть копия этого значения.
ECMAScript 2015 (или ES6) поставляется со встроенным объектом Reflect . Удалить свойство объекта можно, вызвав функцию Reflect.deleteProperty () с целевым объектом и ключом свойства в качестве параметров:
Но если свойство объекта не настраивается, его нельзя удалить ни с помощью функции deleteProperty, ни с помощью оператора delete:
Object.freeze () делает все свойства объекта неконфигурируемыми (кроме прочего). deleteProperty Функция (а также оператор удаления ) возвращает, false когда пытается удалить любое из своих свойств. Если свойство является настраиваемым, оно возвращается true , даже если свойство не существует.
Разница между delete и deleteProperty заключается в использовании строгого режима:
@ Gothdo имеет больше преимуществ, особенно когда вам нужно сделать что-то функциональное. Например , вы можете назначить функцию переменной, передать в качестве аргумента или использования apply , call , bind функции .
Предположим, у вас есть объект, который выглядит так:
Удаление свойства объекта
Если вы хотите использовать весь staff массив, правильным способом будет сделать это:
В качестве альтернативы, вы также можете сделать это:
Точно так же удаление всего массива студентов будет выполнено путем вызова delete Hogwarts.students; или delete Hogwarts['students']; .
Удаление индекса массива
Теперь, если вы хотите удалить одного сотрудника или студента, процедура немного отличается, поскольку оба свойства являются самими массивами.
Если вы знаете индекс своего сотрудника, вы можете просто сделать это:
Если вы не знаете индекс, вам также придется выполнить поиск по индексу:
Запись
Хотя технически вы можете использовать delete массив, его использование приведет к неправильным результатам при вызове, например, Hogwarts.staff.length позже. Другими словами, delete удалит элемент, но не обновит значение length свойства. Использование delete также может испортить вашу индексацию.
Таким образом, при удалении значений из объекта всегда сначала учитывайте, имеете ли вы дело со свойствами объекта или со значениями массива, и выбирайте соответствующую стратегию на основе этого.
Если вы хотите поэкспериментировать с этим, вы можете использовать эту скрипку в качестве отправной точки.
У меня есть глобальная переменная в JavaScript (на самом деле window свойство, но я не думаю, что это имеет значение), который уже был заполнен предыдущим скриптом, но мне не нужен другой скрипт, который будет запущен позже, чтобы увидеть его значение или что он был даже определен.
Я положил some_var = undefined и он работает с целью тестирования typeof some_var == "undefined" но я действительно не думаю, что это правильный путь.
12 ответы
delete Оператор удаляет свойство объекта. Он не может удалить переменную. Таким образом, ответ на вопрос зависит от того, как определяется глобальная переменная или свойство.
(1) Если он создан с помощью var , его нельзя удалить.
(2) Если он создан без var , его можно удалить.
Техническое объяснение
1. С помощью var
В этом случае ссылка g_a создается в том, что называется спецификацией ECMAScript "Переменная среда", который прикреплен к текущей области видимости - это может быть контекст выполнения функции в случае использования var внутри функции (хотя это может быть немного сложнее, если учесть let ) или в случае «глобального» кода Переменная среда прикреплен к глобальному объекту (часто window ).
Ссылки в Переменная среда обычно не удаляются - процесс подробно описан в ECMAScript 10.5 подробно объясняет это, но достаточно сказать, что если ваш код не выполняется в eval context (который используется в большинстве браузерных консолей разработки), затем переменные, объявленные с var не может быть удален.
2. Без использования var
При попытке присвоить значение имени без использования var ключевое слово, Javascript пытается найти указанную ссылку в том, что называется спецификацией ECMAScript "Лексическая среда", а главное отличие в том, что Лексическая средаs вложены - это Лексическая среда имеет родителя (то, что спецификация ECMAScript называет «ссылкой на внешнюю среду»), и когда Javascript не может найти ссылку в Лексическая среда, он смотрит в родительский Лексическая среда (как подробно описано в 10.3.1 и 10.2.2.1). Верхний уровень Лексическая среда это "глобальная среда", и это связано с глобальным объектом в том смысле, что его ссылки являются свойствами глобального объекта. Поэтому, если вы попытаетесь получить доступ к имени, которое не было объявлено с помощью var ключевое слово в текущей области или любых внешних областях, Javascript в конечном итоге получит свойство window объект, служащий этой ссылкой. Как мы узнали ранее, свойства объектов можно удалять.
Заметки
Важно помнить, что var объявления "приподняты" - т.е. они всегда считаются произошедшими в начале области видимости, в которой они находятся - но не инициализация значения, которая может быть выполнена в var заявление - это осталось там, где оно есть. Итак, в следующем коде a это ссылка из Переменная среда и не window свойство и его стоимость будет 10 в конце кода:
Вышеупомянутое обсуждение касается случая, когда «строгий режим» не включен. Правила поиска немного отличаются при использовании «строгого режима», и лексические ссылки, которые разрешились бы в свойствах окна без «строгого режима», вызовут ошибку «необъявленная переменная» в «строгом режиме». Я действительно не понял, где это указано, но это то, как ведут себя браузеры.
Читайте также: