Где хранится переменная в замыкании, в случае конструктора?
Допустим у нас есть код:
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 и находится через замыкание, то тогда эти два экземпляра должны мешать друг другу, перезаписывая значения друг друга. Если они не мешают друг другу, значит этот массив каким-то образом принадлежит объекту, но где "там" он лежит?...:-? Спасибо. |
Очень важно понимать в какой момент и почему происходит замыкание.
Сохранение всего лексического окружения в момент совершения определенного действия при исполнении кода. Тогда ответ станет очевидным. Конечно можно дать четкое и понятное разъяснение но это не поможет тебе разобраться в механике работы самой мощной в плане возможностей части JS. |
function User(fullName) {
this.fullArr = fullName.split(' ')
}
User.prototype = {
get firstName() {
return this.fullArr[0];
},
set firstName(value) {
this.fullArr[0] = value;
},
}
// или
// Object.defineProperty(User.prototype, 'firstName', {
// get: function () {
// return this.fullArr[0];
// },
// set: function (value) {
// this.fullArr[0] = value;
// },
// })
Вообще код должен был выглядеть примерно так... почему? :) https://github.com/azat-io/you-dont-...%D0%B8%D 1%8F https://github.com/azat-io/you-dont-...ect-prototypes https://github.com/azat-io/you-dont-know-js-ru |
Код был приведён специально для того, чтоб задать вопрос по замыканию. В Ваших интерпритациях, SuperZen, никакого замыкания, нет, а значит и вопрос задавать не к чему...
|
Мужик, я могу понять таб в четыре пробела, хотя в два - гораздо приятней, но в десять? Зачем?
По вопросу: каждое исполнение функции имеет свой контекст. Каждое создание функции может замыкать переменные из вышестоящего контекста. При исполнении функции User создаётся контекст, в котором лежит fullArr. При исполнении функции User создаются новые функции-геттеры и функции-сеттеры, которые замыкают на себя вышестоящий контекст. |
Aetae
я правильно понимаю, что каждое исполнение функции, создаёт новые переменные и, если результаты этой функции, мы куда-то сохраняем (в какую-то внешнюю, по отношении к функции, переменную), то только эта переменная замыкается на конкретное исполнение функции? То есть, объект, на который ссылается переменная vasya, и объект, на который ссылается переменная masha, замыкается на конкретное исполнение User, поскольку каждое исполнение независимо и мы о них "помним" только потому, что у каждого из этих объектов, есть ссылка на свою переменную fullArr, сохранившуюся со времён исполнения функции User (при создании конкретного экземпляра объекта)? При этом, если мы избавимся от конструктора new: 1. уберём new перед переменными. 2. перед геттеро-сеттерами объявим новый объект var object = new Object (или просто = {} ). 3. вместо this в геттерах-сеттерах укажем object. 4. в конце функции вернём return object; то всё точно также будет работать, поскольку логика замыкания не изменится... Всё верно или есть ещё какие-то важные, для понимания, детали? Вы что-то говорили про контекст?... |
Вроде всё верно.
Цитата:
|
Ясненько. Спасибо, теперь, в общем-то ясно...
Получается у нас может быть относительно "простенький" объект, у которого 2,5 поля, а внутри тысячи внутренних переменных сложно регулирующих его поведение... А можно как-то выяснить, есть ли у объекта какое-то "двойное дно" или, стандартными средствами, это в общем-то, почти нереальная задача?... |
Launder, можно посмотреть в код.)
Ну или на растущую память. Нет таких задач где бы потребовалось отличать такой объект, потому что это не что-то особенное, а один и бесконечности вариантов написания кода. |
Спасибо всем откликнувшимся! Иногда понимаю, что не понимаю, или не достаточно понимаю, каких-то базовых вещей, поэтому придумываю какие-то достаточно простые примеры, чтоб работа какой-то технологии стала очевидной. Большое спасибо за наводки, вроде, в первом приближении, разобрался :)
|
| Часовой пояс GMT +3, время: 09:18. |