14.06.2020, 12:08
|
Интересующийся
|
|
Регистрация: 25.04.2019
Сообщений: 19
|
|
Где хранится переменная в замыкании, в случае конструктора?
Допустим у нас есть код:
function User(fullName)
{
var fullArr = fullName.split(' '); //делаем массив
Object.defineProperty(this, 'firstName',
{
get: function()
{
return fullArr[0]; //выдаём первый элемент массива
},
set: function(value)
{
fullArr[0] = value; // записываем первый элемент массива
}
} );
Object.defineProperty(this, 'lastName',
{
get: function()
{
return fullArr[1]; //выдаём второй элемент массива
},
set: function(value)
{
fullArr[1] = value; //записываем второй элемент массива
}
} );
Object.defineProperty(this, 'fullName',
{
get: function()
{
return fullArr[0] + ' ' + fullArr[1]; //выдаём весь массив, через пробел
},
set: function(value)
{
fullArr = value.split(' '); //записываем массив из строки
}
} );
}
var vasya = new User("Василий Тёркин");
var masha = new User("Мария Шарапова");
Итак у нас два разных пользователя. Они, насколько я понимаю, ничем друг другу не мешают. Но мне до конца не понятен механизм их образования: оператор new генерирует создание нового объекта, функция выполняется и выдаёт этот новый объект. Но! Массив fullArr где хранится? если он лежит в функции(конструкторе) User и находится через замыкание, то тогда эти два экземпляра должны мешать друг другу, перезаписывая значения друг друга. Если они не мешают друг другу, значит этот массив каким-то образом принадлежит объекту, но где "там" он лежит?... Спасибо.
|
|
14.06.2020, 12:36
|
|
Профессор
|
|
Регистрация: 07.03.2011
Сообщений: 1,138
|
|
Очень важно понимать в какой момент и почему происходит замыкание.
Сохранение всего лексического окружения в момент совершения определенного действия при исполнении кода.
Тогда ответ станет очевидным.
Конечно можно дать четкое и понятное разъяснение но это не поможет тебе разобраться в механике работы самой мощной в плане возможностей части JS.
|
|
18.06.2020, 14:18
|
Интересующийся
|
|
Регистрация: 25.04.2019
Сообщений: 19
|
|
Код был приведён специально для того, чтоб задать вопрос по замыканию. В Ваших интерпритациях, SuperZen, никакого замыкания, нет, а значит и вопрос задавать не к чему...
|
|
18.06.2020, 15:17
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,590
|
|
Мужик, я могу понять таб в четыре пробела, хотя в два - гораздо приятней, но в десять? Зачем?
По вопросу: каждое исполнение функции имеет свой контекст. Каждое создание функции может замыкать переменные из вышестоящего контекста.
При исполнении функции User создаётся контекст, в котором лежит fullArr. При исполнении функции User создаются новые функции-геттеры и функции-сеттеры, которые замыкают на себя вышестоящий контекст.
__________________
29375, 35
|
|
18.06.2020, 18:57
|
Интересующийся
|
|
Регистрация: 25.04.2019
Сообщений: 19
|
|
Aetae
я правильно понимаю, что каждое исполнение функции, создаёт новые переменные и, если результаты этой функции, мы куда-то сохраняем (в какую-то внешнюю, по отношении к функции, переменную), то только эта переменная замыкается на конкретное исполнение функции?
То есть, объект, на который ссылается переменная vasya, и объект, на который ссылается переменная masha, замыкается на конкретное исполнение User, поскольку каждое исполнение независимо и мы о них "помним" только потому, что у каждого из этих объектов, есть ссылка на свою переменную fullArr, сохранившуюся со времён исполнения функции User (при создании конкретного экземпляра объекта)?
При этом, если мы избавимся от конструктора new:
1. уберём new перед переменными.
2. перед геттеро-сеттерами объявим новый объект var object = new Object (или просто = {} ).
3. вместо this в геттерах-сеттерах укажем object.
4. в конце функции вернём return object;
то всё точно также будет работать, поскольку логика замыкания не изменится...
Всё верно или есть ещё какие-то важные, для понимания, детали?
Вы что-то говорили про контекст?...
|
|
18.06.2020, 19:09
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,590
|
|
Вроде всё верно.
Цитата:
|
о них "помним" только потому, что у каждого из этих объектов, есть ссылка на свою переменную fullArr, сохранившуюся со времён исполнения функции User
|
А сохранилась она потому, что во время исполнения были созданы новые функции, которые использовали эту переменную. Иначе GC бы просто очистил от неё память, т.к. на неё не осталось бы ссылок.
__________________
29375, 35
|
|
20.06.2020, 20:24
|
Интересующийся
|
|
Регистрация: 25.04.2019
Сообщений: 19
|
|
Ясненько. Спасибо, теперь, в общем-то ясно...
Получается у нас может быть относительно "простенький" объект, у которого 2,5 поля, а внутри тысячи внутренних переменных сложно регулирующих его поведение...
А можно как-то выяснить, есть ли у объекта какое-то "двойное дно" или, стандартными средствами, это в общем-то, почти нереальная задача?...
|
|
21.06.2020, 07:11
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,590
|
|
Launder, можно посмотреть в код.)
Ну или на растущую память.
Нет таких задач где бы потребовалось отличать такой объект, потому что это не что-то особенное, а один и бесконечности вариантов написания кода.
__________________
29375, 35
|
|
21.06.2020, 15:04
|
Интересующийся
|
|
Регистрация: 25.04.2019
Сообщений: 19
|
|
Спасибо всем откликнувшимся! Иногда понимаю, что не понимаю, или не достаточно понимаю, каких-то базовых вещей, поэтому придумываю какие-то достаточно простые примеры, чтоб работа какой-то технологии стала очевидной. Большое спасибо за наводки, вроде, в первом приближении, разобрался
|
|
|
|