Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Замыкания в JS (https://javascript.ru/forum/misc/18080-zamykaniya-v-js.html)

Йакуд 16.06.2011 04:20

Замыкания в JS
 
Всем привет. У меня появился вопрос. Как можно реализовать такую фичу:
Имеется объект

var User = function(id){
  var then = {};	
  then.id = id;	
  
  /*...*/

  then.getInfo = function(param){
    param.id = then.id;
	
    /* Запрос на сервер */
    $.get(then.phpGet, param, function(data){
      /* Парсим данные */
      var data = JSON.parse(data);
	  
      /* Если ошибка, выводим сообщение */
      if(data.error !== undefined){
        then.showError(data.error);
      }
      else /* Добавляем к основному объекту принятые параметры */
      {
        for(var i in data)
        {
          then[i] = data[i];
        }
        
        /* Ссылку/копию передать отсюда. */
        if(param.End !== undefined && typeof(param.End) == "function"){
          param.End(then);
        }
      }
    });
 }
}


Создается он так вот:
var yakud = new User(UserEnter_id);
yakud.getInfo({
  param: ['nick', 'type'],
  End: function(d){
    //alert(d)
  }
});


Все дело в том, что мне нужно вот сюда
End: function(d){
    //alert(d)
}

Передать ссылку или копию объекта then с полученными параметрами.
Как это можно реализовать? Прочитал статью на сайте про замыкания и, честно говоря, мало чего понял.
Буду очень благодарен за помощь.

FINoM 16.06.2011 05:07

В место then использовать this?

Йакуд 16.06.2011 13:25

Собственно, какая разница-то? Объект then у меня создается и в дальнейшем используется он. Тут все в норме.
На самом деле, все само заработало =___=. Но теперь одна ошибочка есть. Функция End вызывается как-будто два раза. Первый раз аргумент undefined, а второй раз возвращает то, что нужно.
Приходится делать проверку на undefined вот в этом месте
End: function(d){ 
  if(d !== undefined)
    alert(d) 
}

Но это не очень красиво. Как можно избежать этой проверки? Да и вообще, почему функция, может вызываться два раза? Хотя вызываю я ее точно один! Я проверял уже.

Nekromancer 16.06.2011 13:42

Цитата:

Сообщение от Йакуд (Сообщение 109031)
Собственно, какая разница-то? Объект then у меня создается и в дальнейшем используется он. Тут все в норме.

Не в норме, вы плодите много лишних объектов.

Про 2 раза не знаем, весь код не видели, мало ли чего вы намудрили.

Йакуд 16.06.2011 13:52

Лишний объект создал из-за того, что буду обращаться из объекта jQuery, а там this уже имеется. Это для своего удобства. Мне кажется, что лишний объект не сильно повлияет на быстродействие.
Цитата:

Про 2 раза не знаем, весь код не видели, мало ли чего вы намудрили.
Это и есть весь код, только без функции вывода ошибки и без инициализации нужных переменных. Но если на то пошло, то вот класс:
var User = function(id){
  var then = {};	
  then.id = id;	
	
  /* Основные переменные */
  then.phpGet = "./model/gb/js/user/user.php";
  then.errorMessage = {
    0: "Вы не имеете доступа к разделу!"
  };
  
  /* Получение информации о пользователе */
  then.getInfo = function(param){
	param.id = then.id;
	
	/* Запрос на сервер */
    $.get(then.phpGet, param, function(data){
	  /* Парсим данные */
	  var data = JSON.parse(data);
	  
	  /* Если ошибка, выводим сообщение */
	  if(data.error !== undefined){
	    then.showError(data.error);
	  }
	  else /* Добавляем к основному объекту принятые параметры */
	  {
	    for(var i in data)
		  then[i] = data[i];

		if(param.onComplete !== undefined && typeof(param.onComplete) == "function")
		   then.End(then);
	  }
	});
  }
  
  /* Функция вывода ошибки */
  then.showError = function(error_id){
    alert("Ошибка №" + parseInt(error_id+1) + "! " + then.errorMessage[error_id]);
  };
  
  return then;
};

Вот создание объекта:
var UserEnter_id = 1;

var yakud = new User(UserEnter_id);
yakud.getInfo({
  param :['nick', 'type'],
  End   :function(d){
    if(d !== undefined)
      alert(d)
  }
});

Вот так вот работает, а без
if(d !== undefined)
вызывается два раза. Нужно как-нибудь избавится от этого условия и чтобы функция, вызывалась только один раз. Если поставить условие в классе, то это погоды не сделает, т.к. я уже говорил, что функция вызывается точно только один раз.

Nekromancer 16.06.2011 14:08

Вообще "get" в jQuery багнутая, в старых версиях она в опере 2 раза вызывала callback, скорее всего в этом дело.
На счёт объекта лишнего ..
Если вы объект используете по ссылке this не обязательно на неё и передавать, можно спокойно передавать как аргумент функции.

Йакуд 16.06.2011 15:07

Все, я разобрался в чем проблема... Проблема была вовсе не в get и не в jQuery. Дело в том, что я передавал через get не те данные. Я передавал объект, а нужно было массив.
Вместо
$.get(then.phpGet, param, function(data){
  /* ... */
});
Нужно было
$.get(then.phpGet, param.param, function(data){
  /* ... */
});

Т.к. в функцию then.getInfo я передавал не массив, а объект содержащий в себе массив, отсюда и был лишний вызов функции.
Всем спасибо за отклик!


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