Где хранится переменная в замыкании, в случае конструктора?
Допустим у нас есть код:
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, время: 23:52. |