Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Конструктор внутри конструктора 
:(
    Опции темы
Greendrake
Дата 22.2.2006, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 364
Регистрация: 14.7.2005

Репутация: нет
Всего: 6



Нужно сделать конструктор, содержащий другой конструктор, так, чтобы объект второго можно было создавать через вызов соответствующего метода объекта от первого конструктора.

Что-то типа вот этого,

Код

<script type="text/javascript" language="JavaScript">
  function object1()
  {
    function object2()
    {
      this.doIt=function()
      {
            alert('it\'s me, method of object2');
      };
    };
  };  
  var o1 = new object1();
  var o2 = new o1.object2();
  o2.doIt();
</script>


или

Код

<script type="text/javascript" language="JavaScript">
  function object1()
    {
      this.object2=function(){};
      this.object2.doIt=function()
      {
        alert('it\'s me, method of object2');
      };
    };  
    var o1 = new object1();
    var o2 = new o1.object2();
    o2.doIt();
</script>



но что бы работало. Почему ни один из этих двух кодов не пашет?
PM MAIL   Вверх
Greendrake
Дата 22.2.2006, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 364
Регистрация: 14.7.2005

Репутация: нет
Всего: 6



Урааа, нашёл решение!

Код

    function object1()
    {
        this.object2=function()
        {
          this.doIt=function()
          {
            alert('it\'s me, method of object2');
          };
        };
    };  
    var o1 = new object1();
    var o2 = new o1.object2();
    o2.doIt();


Всем спасибо за внимание smile
PM MAIL   Вверх
Sardar
Дата 23.2.2006, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Greendrake, зачем это? smile
Любая функция (метод) может быть конструктором, что ты и сделал, определил функцию и запользовал её как конструктор. Можешь и как простой метод вызват, будет this текущим обьектом (object1)

Советую определять методы в прототипе, всё таки логичней создавать одну функцию на все обьекты, чем каждому по closure (когда в конструкторе), да и памяти меньше хавает. Пример:

Код
  function object1()  {
   alert(" Object 1 constructor" );
 }

object1.prototype.object2 = function() {
            alert('it\'s me, method of object2');
}

var o1 = new object1();
var o2 = new o1.object2();
o2.doIt();

alert(o1.doIt);
o1.object2(); //  ;-)
alert(o1.doIt)


Можно узнать задачу где это понадобилось? Просто логики мало, возможно ты хотел представить вложенный класс как в Java, но в Java механизм совершенно другой, там вложенный не статический класс имеет доступ до полей внешнего класса (обьекта), что удобно например для построения эффективных итераторов. Только JS это не Java, здесь это можно сделать проще smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Greendrake
Дата 23.2.2006, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 364
Регистрация: 14.7.2005

Репутация: нет
Всего: 6



Цитата(Sardar @ 23.2.2006, 11:33)
зачем это? smile Можно узнать задачу где это понадобилось?

Конечно.

Я разрабатываю свою CMS. На произвольно запрошенной странице могут находиться совершенно различные блоки (DIV, table - не важно). Где-то будут одни и те же, где-то разные. Многие блоки будут динамическими, т. е. иметь свой "обслуживающий их" JavaScript. Также нужно организовывать взаимодействие этих блоков. Мне показалось вполне логичным решением для каждого динамического блока создать конструктор и инициализировать соответствующий одноимённый объект.

Так вот одним из этих блоков является так называемый RequestDiv. Неотображаемый див, использующийся для временного хранения текстовых результатов запросов по XMLHTTPRequest. Он инициализируется в виде объекта. Сам див - одно из его полей. Я решил что будет логично, если объект XMLHTTPRequest будет каждый раз создаваться НЕ некой глобальной функцией getRequestObject, а конструктором внутри этого RequestDiv. Раскритикуйте, если это не логично / не верно / не оптимально.

Код

function RequestDiv()
{
  this.req=function()
  {

    // создаём this.r - простой кроссбраузерный XMLHttpRequest
    if (window.XMLHttpRequest) {this.r=new XMLHttpRequest();}
    else
    {
    try
    {
      this.r=new ActiveXObject('Msxml2.XMLHTTP');
    }
    catch(e)
    {
      this.r=new ActiveXObject('Microsoft.XMLHTTP');
    };
    };
    
    // пишем простой метод для GET-запросов
    this.request=function(url)
    {
      this.r.open('GET',url,true);
      this.r.send(null);
    };
  };

  // привязываем DIV, чтоб был
  this.div=document.getElementById('requestDiv');

};

var rDiv = new RequestDiv();

var req = new rDiv.req();

// ну и дальше назначаем onreadystatechange и делаем запрос...


Допускаю, что буду послан использовать решение от Котерова, но мне такая громоздкая штука не нужна, т. к. ориентируюсь тока на последние браурезы.

Это сообщение отредактировал(а) Greendrake - 23.2.2006, 17:03
PM MAIL   Вверх
Greendrake
Дата 23.2.2006, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 364
Регистрация: 14.7.2005

Репутация: нет
Всего: 6



Впрочем ладно, я уже передумал smile . Я просто сразу не додумался, что вовсе не обязательно сразу в страницу втыкать неотображаемый DIV: его можно создать динамически и пользоваться им, не привязывая его к странице вообще. Поэтому и необходимость вложенных конструкторов отпала (пока smile ). Вот:

Код

      function req()
      {
        this.div=document.createElement('DIV');
        if (window.XMLHttpRequest) {this.r=new XMLHttpRequest();}
        else {
          try {this.r=new ActiveXObject('Msxml2.XMLHTTP');}
          catch(e) {this.r=new ActiveXObject('Microsoft.XMLHTTP');};
        };
        this.request=function(url) {
          this.r.open('GET',url,true);
          this.r.send(null);
        };
        this.r.onreadystatechange = function(){alert(this.readyState);};
      };
      var req = new req();
      req.request('/x.html');


Что любопытно - в строчке 13 внутри алерта this воспринимается по-разному в Опере и Лисе. Так, в Опере this в этом контексте - сам XMLHttpRequest, и в алерте выдаётся его readyState. В Лисе этот this - сама функция - обработчик onreadystatechange. В IE этот this - некий объект, какой не понял (но, по-видимому, то же что в Лисе). Как быть?

Это сообщение отредактировал(а) Greendrake - 23.2.2006, 17:37
PM MAIL   Вверх
Sardar
Дата 23.2.2006, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(Greendrake @ 23.2.2006, 13:32 Найти цитируемый пост)
Мне показалось вполне логичным решением для каждого динамического блока создать конструктор и инициализировать соответствующий одноимённый объект.

Может быть громоздко, если типов блоков много.

Greendrake, Скажи мне, зачем тебе RequestDiv? он создает XMLHttpRequest, затем отдаёт его тебе, где ты сам работаешь с onreadystatechange и т.д. А не проще ли было:

Код
//.....
var tgt = document.getElementById('my_target_element');
var req = requestBlaBla(url, function(data) { //функция будет вызвана когда придут данные
  if(data == null) { //была ошибка
     reportError("Дорогой юзер, сегодня не твой день...");
     showTryAgainDialog(url, tgt.id); //вдруг юзер захочет по новой, общая функция запустит новый запрос
  }
  //инфа дошла, она в data, допустим это responseXML, что то подобное
  // <response>
  //  <bla-bla-info>
  //    <info key="bla-bla">value</info>
  //  </bla-bla-info>
  //  <data>
  //    <type>text/plain</type>
  //    <content>просто текст</content>
  //  </data>
  // </response>
  tgt.innerHTML = data.selectSingleNode('data/content').text; // "просто текст"
},
 3 //хорошо бы количество попыток задать
);

Такой код удобней, не нужно ничего знать о XMLHttpRequest, просто знаем что пришла инфа - всё ОК, пришло null - была ошибка. Вложенный closure "видит" все переменные выше по контексту где был определён, потому не нужно записывать все необходимые переменные в поля временного обьекта, как ты бы это сделал в Java.
Если подход понравился, покажу как реализовать smile

Цитата(Greendrake @ 23.2.2006, 16:32 Найти цитируемый пост)
Поэтому и необходимость вложенных конструкторов отпала

Необходимости во "вложенных конструкторах" никогда не было, такого термина в JS даже нет smile Определяй методы обьектов в prototype, помни что это не классы Java. Каждый раз определяя методы в конструкторе ты создаёшь новые обьекты-функции (closures) для каждого создаваемого обьекта, это не экономно в памяти, да и просто не красиво. И вообще совет, освободи своё сознание от впаянного тебе ООП из Java, писать "настоящим ООП" можно проще, без шаманских трюков smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Greendrake
Дата 24.2.2006, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 364
Регистрация: 14.7.2005

Репутация: нет
Всего: 6



Цитата(Sardar @ 23.2.2006, 23:49)
Может быть громоздко, если типов блоков много.

Но ведь по-любому не более громоздко, чем если весь JS, обслуживающий все возможные блоки, пихать в один файл в виде безвкусного набора глобальных функций? Надоела мне эта каша, хочу структурированности и логической стройности. "Эффективных интерфэйсов", панимаеш smile.


Цитата(Sardar @ 23.2.2006, 23:49)
Такой код удобней, не нужно ничего знать о XMLHttpRequest ... Если подход понравился, покажу как реализовать smile

Собственно я и заварил кашу чтобы не вспоминать про XMLHttpRequest, и от работы с onreadystatechange пытался уйти. Благодарю за пример, попробую переварить и реализовать, если что не получится, буду просить помочь...


Цитата(Sardar @ 23.2.2006, 23:49)
Определяй методы обьектов в prototype, помни что это не классы Java. Каждый раз определяя методы в конструкторе ты создаёшь новые обьекты-функции (closures) для каждого создаваемого обьекта, это не экономно в памяти, да и просто не красиво.

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

Цитата(Sardar @ 23.2.2006, 23:49)
И вообще совет, освободи своё сознание от впаянного тебе ООП из Java
А я Java вообще не знаю кстати smile. Моё ООПшное сознание ещё формируется, отовсюду по чуть-чуть smile.
PM MAIL   Вверх
Sardar
Дата 24.2.2006, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(Greendrake @ 23.2.2006, 23:22 Найти цитируемый пост)
То есть для каждого динамического блока создавать пустой конструктор, и редактировать его прототип, а уже потом создавать этим конструктором объекты? Типа только в этом случае методы разных объектов от этого конструктора будут физически в памяти одними и теми же?

не совсем, в конструкторе ты иницализируешь обьект, document.getElementById необходимые элементы, создаёшь чего специфичное для конкретного обьекта. Интерфейс же обьекта (его методы), определяем в прототипе, тогда да, физически на все обьекты будет один экземпляру функции на каждый метод.
Добавлено @ 11:35
Цитата(Greendrake @ 23.2.2006, 23:22 Найти цитируемый пост)
Но ведь по-любому не более громоздко, чем если весь JS, обслуживающий все возможные блоки, пихать в один файл в виде безвкусного набора глобальных функций? Надоела мне эта каша, хочу структурированности и логической стройности. "Эффективных интерфэйсов", панимаеш

Я же не говорил плодить кучу функций и скидывать в одну простыню, просто писать для каждого типа окошка/элемента конструктор, что создаёт обьект, который ты затем не используешь вовсе... это не то что бы не красиво, это не ООП, а процедурный подход, где вызовы функций заменены на вызовы конструткоров. Извини если не правильно понял, кода твоего не видел smile

P.S. сам "фанат" ООП, но после не малого опыта со скриптовыми окружениями понял где она граница между логикой и "фарисейством"


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.4762 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.