Копирование и удаление переменных(обьектов).
Здравствуйте, меня интересуют особенности внутренней работы интерпретатора и браузера.
Например: В каком порядке удаляются объекты? Когда переменная копируется по значение а когда по ссылке? ... Может кто то подскажет книжки или статьи с данной инфой. Заранее благодарен. |
Yazla,
В js переменные со значениями любого типа передаются/копируюся "по-значению", никаких ссылок и проч. в стандарте нет, есть только значения. ECMAScript весь построен на by-value. Нужно только помнить, что в отношении объектов мы работаем со свойствами по ссылке. Но работа со свойствами объекта и работа с переменными - две большие разницы. ;-) Объекты удаляет сборщик мусора (garbage collector), порядок и алгоритм в руках той или иной реализации языка, например, подробнее о JScript . Для программиста важно контролировать, чтобы объект, который он об-null-ил не зацепился за что-либо, что он не увидел. Иначе сборщик его не затрёт. |
Zeroglif, тут, на самом деле, людей сбивает с толку (тех, кто слышал о Reference Type из ES) само слово "Reference", которое ассоциируется со "ссылкой".
В технической же реализации (и описании в стандарте), то поведение, которое осуществляется для объектов, в общей теории - это передача by-sharing. Там как раз чётко описано отличие от передачи by-reference. |
Ну, давай ещё добавим нечто, чтоб не разгрести было вообще. By-value - самое простое, объяснимое и вполне в рамках.
|
Цитата:
function foo(bar) { bar.a = 2; } var baz = {a: 1}; foo(baz); alert(baz.a); // ...если бы вот тут было 1 |
Kolyaj,
Что есть value переменной, если тип объектный? Стандарт этого не раскрывает, но раскрыли давно разработчики языков, там адрес/указатель/нечто... и это не отменяет того факта, что это нечто копируется, стандарт даже не подразумевает ничего другого. Brendan Eich: - value is a *reference* to the object, not the object itself; - the only thing that's copied is a *reference* (a safe pointer, if you will) that uniquely addresses the object; - v2 = v just copies the reference in v into v2, making both variables denote the same object; Выше по ссылке есть ещё несколько цитат от разрабов языков. |
Цитата:
|
Kolyaj,
Ты прав совершенно в первой части - это ссылка, которая передаётся по значению. Именно эта ссылка и есть значение переменной в отношении объектного типа. Круг замкнулся, переменные by-value всегда. ;-) Работа же с объектом (конкретно с его свойствами) происходит по ссылке из любой точки... но это не работа с переменными, это свойства. |
Цитата:
А остальное - это уже локальная терминология: ES называет by-value, Java называет by-value, Ruby называет by-reference - но во всех них в данном случае используется by-sharing. Здесь фишка завязана ещё на связывание имён и объектов в памяти. Именно из-за того, что присваивание переменной объекта, отвязывает переменную от старого места в памяти, и не получается чистый by-reference. Если бы был by-reference, было бы так: function test(a) { a = {x: 20}; } var b = {x: 10}; test(b); alert(b.x); // 20 Если бы был by-value, было бы так: function test(a) { a.x = 20; } var b = {x: 10}; test(b); alert(b.x); // 10 А вот by-sharing, как раз имеет чёткую разницу от них двоих: function test(a) { a.x = 20; } var b = {x: 10}; test(b); alert(b.x); // 20 function test2(a) { // присваивание связывает "а" с новым объектом // старый остаётся нетронутым a = {x: 30}; } test2(b); alert(b.x); // 20 Но именно это связывание переменной с объектом ничем не отличается, если сделать то же самое вне функции и её параметров: var a = {x: 10}; var b = a; // a и b указывают на одно место в памяти alert(b.x); // 10 b = {x: 20}; // связывание с новым объектом, но не апдейт "а" alert(a.x); // 10 Если в рамках ES, то, конечно, можно и by-value говорить, главное знать, что выше этого стоит определение общей теории. С другой стороны, ECMA-262-3 точно это не описывает. Есть куча ссылок (в том числе, которые приводил ты), где, действительно, говорят by-value, но это, опять же, локальная терминология для by-sharing. Может смущать, что работает оператор ===, который возвращает true для локального формального параметра и внешнего объекта (а он возвращает true в данном случае, если операнды указывают на один и тот же объект): function test(a) { alert(a === b); // true } var b = {x: 10}; test(b); Т.е. здесь тоже с толку может сбивать людей - кажется, что "a" - точно не локальный объект, а как будто бы переданный by-reference. Но, во всяком случае, при разрешении "a" и "b", базовые объекты у них разные - для "а" - объект активации, для "b" - глобальный: aRef = {baseObject: AO(test), propertyName: "a"}; bRef = {baseObject: Global, propertyName: "b"}; Каким-то образом затем [[Get]] получает value aRef и bRef и определяет, что они указывают на один объект. |
Цитата:
|
Часовой пояс GMT +3, время: 11:24. |