Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Можно ли заменить замыкание объектом? (https://javascript.ru/forum/misc/54085-mozhno-li-zamenit-zamykanie-obektom.html)

Вячеслав Александрович 03.03.2015 00:42

Можно ли заменить замыкание объектом?
 
Доброго времени суток!
Перечитал кучу умных букав и никак не въеду как работают замыкания. Я понял, что они хранят переменные в локальной области видимости, только не пойму разницу между замыканием и объектом, в котором эта же переменная хранится как свойство. Предложенные в учебных пособиях задачи у меня получалось реализовать с помощью объектов, мне так понятнее что и как работает.
Пример задачи с данного сайта:
function makeCounter() {
  var currentCount = 0;
     
  return function() {
    currentCount++;
    return currentCount;
  };
}
 
var counter = makeCounter();
 
// каждый вызов увеличивает счётчик
counter();
counter();
alert( counter() ); // 3

То, что удалось сделать мне:
var counter = {
	i: 0,
	count: function() {
		return ++counter.i;
	}
}
counter.count();
counter.count();
alert(counter.count());// 3

Работает точно так же, только мне так понятнее и при этом есть возможность обнулять счетчик или менять его значение, присвоив counter.i нужное значение. И код при этом короче.
Подскажите, пожалуйста, есть ли разница и в чем.

Octane 03.03.2015 01:00

Создай одновременно несколько счетчиков и увидишь разницу

Вячеслав Александрович 03.03.2015 01:05

Так можно сколько угодно счетчиков создавать:
function CreateCounter () {
	this.i = 0;
	this.count = function () {
		return ++this.i;
	}
}
var counter = new CreateCounter();
var counter2 = new CreateCounter();
counter.count();
counter.count();
counter2.count();
counter2.count();
console.log(counter.count()); // 3
console.log(counter2.count()); // 3

Все равно не вижу разницы...

Octane 03.03.2015 01:20

Тебе же пришлось изменить код, чтобы создать несколько счетчиков.
То что в итоге получилось у тебя, называется конструктор, а в первом примере была фабрика.
Раз уж пишешь конструктор, так используй прототип, чтобы не создавать каждый раз функцию count:
function CreateCounter () {
    this.i = 0;
}

CreateCounter.prototype.count = function () {
	return ++this.i;
};


Цитата:

Сообщение от Вячеслав Александрович
Все равно не вижу разницы...

ты сам ответил в чем разница
Цитата:

Сообщение от Вячеслав Александрович
есть возможность обнулять счетчик или менять его значение

если этого хотят избежать, замыкают переменную

Вячеслав Александрович 03.03.2015 01:47

Т.е., если я правильно понимаю, разница только в том, что при реализации через замыкание нет доступа к переменной? А, по сути, можно сделать все то же самое, используя объект? Я имею в виду не данную задачу со счетчиком, а в общем.

danik.js 03.03.2015 05:42

Цитата:

Сообщение от Вячеслав Александрович
var counter = new CreateCounter();

Код:

перем счетчик = новый СоздатьСчетчик()
может все таки
Код:

перем счетчик = новый Счетчик()
?

Вячеслав Александрович 03.03.2015 11:34

Это уже не суть важно и не совсем по теме. Я только учусь, так что это норма. На сколько я помню, названия функций принято начинать с глагола. Но это, по ходу, не относится к конструкторам?
На сколько я понял из прочитанного на нескольких сайтах, механизм замыканий точно такой же как и у обычного объекта. Т.е. при создании замыкания в памяти хранится точно такой же объект, но доступ к переменным только через возвращенную функцию.


Часовой пояс GMT +3, время: 16:05.