Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Проблема с this (https://javascript.ru/forum/misc/53370-problema-s.html)

Decode 31.01.2015 19:44

Проблема с this
 
Приветствую. Прошу помочь разобраться с работой данного кода:

function Machine() {
	this._enabled = false;
	var self = this; // ссылка на объект создаваемый CoffeeMachine

	this.enable = function() {
		// внешняя переменная вместо this
		self._enabled = true;
	};

	this.disable = function() {
		this._enabled = false;
	};
}

function CoffeeMachine() {
	Machine.apply(this, arguments);

	var parentEnable = this.enable;
	this.enable = function() {
		parentEnable();
		/// this.run(); и другие методы
	}
}
var coffeeMachine = new CoffeeMachine();
coffeeMachine.enable();

В переменную parentEnable копируется эта функция:
function() {
   self._enabled = true;
};

Когда происходит вызов coffeeMachine.enable() — будет запущена функция parentEnable. Меня вводит в заблуждение переменная self внутри нее. Она ведь локальная переменная другой функции. Внутри функции Machine она доступна через замыкание. Но parentEnable находится внутри конструктора CoffeeMachine. Как она там доступна?

Aetae 31.01.2015 20:24

Нет. parentEnable - это лишь ссылка на функцию, а функция та "находится" там где и была создана.

Decode 31.01.2015 22:16

Ааа, ну тогда все становится понятно.

Aetae, спасибо за разъяснение.

Decode 09.02.2015 17:43

И тут я понял, что ничего не понял :D

function Machine() {
	this._enabled = false;
	var self = this; // ссылка на объект создаваемый CoffeeMachine

	this.enable = function() {
		// внешняя переменная вместо this
		self._enabled = true;
	};

	this.disable = function() {
		this._enabled = false;
	};
}

function CoffeeMachine() {
// при запуске new CoffeeMachine создается новый объект {}
	Machine.apply(this, arguments); // происходит вызов в контексте этого объекта
// Функция Machine вписывает в него свои св-ва и методы: _enabled, enable, disable
	var parentEnable = this.enable; // ссылка на функцию объявленную в Machine? Или ссылка на функцию которую Machine вписал в создаваемый объект?
	this.enable = function() { // переопределение оригинального метода
		parentEnable();
		/// this.run(); и другие методы
	}
}
var coffeeMachine = new CoffeeMachine();
coffeeMachine.enable();




Почему parentEnable в замыкании понятно. Почему функция Machine оказалась там? Ведь она же просто вызвана, но не объявлена в CoffeMachine.

jsnb 09.02.2015 17:57

Цитата:

Сообщение от Decode
Почему функция Machine оказалась там?

Где там? Я вижу вызов функции Machine внутри CoffeeMachine и ничего необычного в этом нет т.к. Machine определена в области видимости выше.

Цитата:

Сообщение от Decode
ссылка на функцию объявленную в Machine? Или ссылка на функцию которую Machine вписал в создаваемый объект?

Второе. Machine вписывает новую функцию enable в каждый инстанс.

Decode 09.02.2015 18:10

Цитата:

Сообщение от jsnb (Сообщение 355862)
Где там? Я вижу вызов функции Machine внутри CoffeeMachine и ничего необычного в этом нет т.к. Machine определена в области видимости выше.

На скрине. Там два Closure, это ведь замыкание? Там parentEnable и Machine.

Aetae 09.02.2015 19:35

Decode, вообще я думал что под "находится" вы понимаете scope. Но судя по всему это не так.
Тогда попробую разъяснить: функции(объекты и проч.) находятся исключительно в памяти и больше нигде. Всё остальное - ссылки. От того "места" где функция была создана зависят только переменные, что она на себя замыкает.

Decode 10.02.2015 03:26

Цитата:

Сообщение от Aetae (Сообщение 355870)
[b]функции(объекты и проч.) находятся исключительно в памяти и больше нигде.

Это я понял.

Получается что... Блин, это пример вообще меня запутал.

Decode 10.02.2015 15:55

Aetae, я верно изобразил схему?

http://jsfiddle.net/fk6q6ad8/


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