Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 26.02.2013, 12:51
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

var popup = popupObject.constuctor('/ajax/popup_delivery.php', {id: 123}, success);
console.log(popupObject.url); // что выдаст? Зачем это свойство хранится?
Сообщение от Василий Б.
ради удобства разработки.
А чем конструкторы не удобны?
Ответить с цитированием
  #12 (permalink)  
Старый 26.02.2013, 13:38
Аспирант
Отправить личное сообщение для Василий Б. Посмотреть профиль Найти все сообщения от Василий Б.
 
Регистрация: 01.03.2010
Сообщений: 44

Сообщение от danik.js
А чем конструкторы не удобны?
Вы про какие конструкторы? Объявление через
function foo()
{
   this.prop = ...
}

?

Сообщение от danik.js
что выдаст? Зачем это свойство хранится?
выдаст URL определенный в конструкторе при первом вызове
popupObject.constructor(...)

Вы что предлагаете? Сделать "uset" или.. вообще не писать в popupObject? Вот так:
constuctor: function(url, data, success){
		// Поскольку в JS нет классов, то мы создаем копию данного объекта (this)
		// и возвращаем его, что бы иметь возможность создавать несколько экземпляров объекта popupObject.
		var o = new Object();
		for (var i in this) {
			if (this.hasOwnProperty(i)) {
				o[i] = this[i];
			}
		}
				
		// свойства назначаем только конкретному объекту 
		o.url = url;
		o.data = data !== undefined ? data : this.data;
		o.success = success !== undefined ? success : this.success;
		return o;
	},
Так?

Последний раз редактировалось Василий Б., 26.02.2013 в 13:44.
Ответить с цитированием
  #13 (permalink)  
Старый 26.02.2013, 17:20
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Василий Б.
а что должно быть в create методе?
по-поему, ничего. вы пытаетесь из синглетона класс.

это ... как из дивана пытаться делать завод по изготовлению мебели. надеюсь, меня поняли

Сообщение от Василий Б.
и это работает,
а это называется примесью.

рекомендую открыть learn.javascript.ru и почитать про способы создание объектов ... там уже есть вся инфа

Сообщение от Василий Б.
ради удобства разработки. да я и не пытаюсь изобрести классы.
а код и сообщения указывают на обратное.

Сообщение от Василий Б.
Вы про какие конструкторы?
те, которые функции, которые имеют имена с большой буквы и те, которые используются с оператором new

еще раз рекомендую открыть learn.javascript.ru
function Blah () {

}

var myBlah = new Blah();
Ответить с цитированием
  #14 (permalink)  
Старый 26.02.2013, 18:13
Аспирант
Отправить личное сообщение для Василий Б. Посмотреть профиль Найти все сообщения от Василий Б.
 
Регистрация: 01.03.2010
Сообщений: 44

да читал я 20 раз это все уже. меня интересует оптимальный подход создания объектов а-ля класс.

Конструкторы мне не нравятся. Они не логичны что ли... вот я на конструкторе писал класс для работы с Аякс:

function Ajax()
{
    /**
     * Экземпляр XMLHttpRequest.
     * 
     * @access private
     * @var object XMLHttpRequest
     */
    var req;

    /**
     * HTTP-заголовки
     * 
     * @access private
     * @var array
     */
    var httpHeaders = {"If-Modified-Since" : "Sat, 1 Jan 2000 00:00:00 GMT"}

    /**
     * Описания статусов readyState
     * 
     * @access private
     * @var array
     */
    var statuses = ['Не инициализиован',
                    'Метод open() вызван, запрос не отправлен',
                    'Запрос был передан',
                    'Ответ сервера принят частично',
                    'Данные приняты, соединение закрыто'];

    this.addUniqueQS = false;
    
    /**
    * Создает объект XMLHttpRequest
    * 
    * @param void
    * @return XMLHttpRequest|null
    */
    (function()
    {
        if (window.XMLHttpRequest) {
            try {
                req = new XMLHttpRequest();
            } catch (e){}
        }
        // only IE 6 =< 
        else if (window.ActiveXObject) {
            try {
                var aVersions = ["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0", 
                                 "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp",
                                 "Msxml2.XMLHTTP", 'Microsoft.XMLHTTP'];

                for (var j in aVersions)
                {
                    try {
                        req = new ActiveXObject(aVersions[j]);
                        break;
                    } catch (e){}
                }
            } catch (e){}
        }

        if (!req)
        {
            throw new Krugozor_Exception(_CONFIG.messages[_CONFIG.lang].ajax.xmlhttprequest_not_found);
        }
    })();

    /**
     * Метод принимает в качестве аргумента анонимную функцию,
     * которая привязывается к обработчику onreadystatechange.
     * Функция должна иметь интерфейс для принятия двух объектов:
     * - первый объект - ссылка на Ajax объект
     * - второй объект - ссылка на объект xmlHttpRequest 
     * 
     * @param object 
     * @return void
     */
    this.setObserverState = function(observer_function)
    {
        var ajax_object = this;
        var req_object = req;

        this.observerState = function()
        {
            if (req_object.readyState == 4) {
                if (req_object.status == 200) {
                    observer_function(ajax_object, this);
                }
            }
        }

        return this;
    }
    
    /**
     * Абстрактный предопределяемый метод, привязанный
     * к обработчику onreadystatechange.
     * Пример предопределения в клиентском скрипте:
     * 
     * var ajax = new Ajax();
     * ajax.observerState = function()
     * {
     *     if (ajax.getHttpRequest().readyState == 4) {
     *         if (ajax.getHttpRequest().status == 200)
     *         {
     *             alert(ajax.getHttpRequest().responseText)
     *         }
     *     }
     * }
     *
     * @param void
     * @return mixed
     */
    this.observerState = function()
    {
        if (req.readyState == 4) {
            if (req.status == 200) {
                alert('Метод observerState должен быть предопределен перед использованием объекта');
            }
        }
    }

    /**
     * Отправляет GET-запрос по адресу url
     * 
     * @param string url
     * @param boolean синхронность запроса.
     *        true - асинхронный, false - синхронный
     * @return void
     */
    this.get = function(url, synchronicity)
    {
    	if (arguments.length == 1)
    	{
    		synchronicity = true;
    	}
    	
        if (!!this.addUniqueQS)
        {
        	url += (url.indexOf('?') == -1 ? '?' : '&') + Math.floor(Math.random()*1000);   
        }
        
        req.open('GET', url, !!synchronicity);

        this.sendHeaders();

        if (synchronicity)
        {
            req.onreadystatechange = this.observerState;
        }

        req.send(null);

        return this;
    }

    /**
     * Устанавилвает заголовок HTTP с ключом key 
     * и значением value.
     * 
     * @access public
     * @param key имя HTTP-заголовка
     * @param value значение HTTP-заголовка
     * @return void
     */
    this.setHeader = function(key, value)
    {
        httpHeaders[key] = value;
    }

    /**
     * Отправляет HTTP-заголовки.
     * 
     * @access private
     * @param void
     * @return void
     */
    this.sendHeaders = function()
    {
        for (var i in httpHeaders)
        {
            if (typeof httpHeaders[i] == 'string')
            {
                req.setRequestHeader(i, httpHeaders[i]);
            }
        }
    }

    /*  Методы получения ответа (XMLHttpRequest) и результата из ответа */

    /**
     * Возвращает экземпляр объекта XMLHttpRequest
     *
     * @param void
     * @return object req
     */
    this.getHttpRequest = function()
    {
        return req;
    }

    /**
     * Возвращает статус HTTP
     * 
     * @param void
     * @return int
     */
    this.getStatus = function()
    {
        return req.status;
    }

    /**
     * Возвращает стандартный объект JS, который является
     * "сериализованным" объектом в виде строки текста ответа - JSON.
     *
     * @access public
     * @param void
     * @return object
     */
    this.getJson2HashByKey = function()
    {
        return eval( "(" + req.responseText + ")" );
    }

    /**
     * Возвращает текст ответа сервера
     *
     * @access public
     * @param void
     * @return string
     */
    this.getText = function()
    {
        return req.responseText;
    }
}

Пример использования:

// Для асинхронных запросов:
    var async_ajax = new Ajax();
    async_ajax.setObserverState(
        function(ajx, xhr) {
            alert( ajx.getJson2HashByKey() + '   ' + xhr.responseText);
        }
    ).get("/ajax/country");



Ещё один способ пробовал, но это я так понимаю jQuery стиль и это сингелтон:
var click = (function(){
    var prop = '...';
    var method = function(){
        // do it 
    }

    return {
        init: method
    }
})();

var myClick = click.init();
и т.д.

Этот способ по вашему лучше, чем описанный в первом посте?

Последний раз редактировалось Василий Б., 26.02.2013 в 18:22.
Ответить с цитированием
  #15 (permalink)  
Старый 26.02.2013, 19:18
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Василий Б.
Этот способ по вашему лучше, чем описанный в первом посте?
этот способ тоже ужасен.

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

идти против языка нет смысла - только добавит тормозов

конечно, можно заюзать библиотеки для облегчения объектного программирования, но это уже сами
Ответить с цитированием
  #16 (permalink)  
Старый 27.02.2013, 11:03
Аспирант
Отправить личное сообщение для Василий Б. Посмотреть профиль Найти все сообщения от Василий Б.
 
Регистрация: 01.03.2010
Сообщений: 44

melky,
Цитата:
в JavaScript прототипное программирование... а это значит, что вы должны писать таким способом, и более пока никак
ок. как создать "класс" более правильно?
Я кажется понимаю что такое прототип и чем он отличается от свойства объекта:
function Base(){
	this.f11 = function(){alert('call Base::f11')}
};
Base.prototype.f1 = function(){alert('call Base::f1');}

function Parent(){
	this.f11 = function(){alert('call Parent::f11')}
}
Parent.prototype.f1 = function(){alert('call Parent::f1')}
Parent.prototype = new Base();

var o = new Parent();
o.f1(); // `call Base::f1` - перезагрузили Parent::f1 методом из прототипа Base?
o.f11(); // `call Parent::f11` - перезагрузки не произошло, т.к. ф-ия f11() - свойство объекта, а не прототипа

правильно ли я понимаю отличие прототипа от свойства объекта?

Последний раз редактировалось Василий Б., 27.02.2013 в 11:23.
Ответить с цитированием
  #17 (permalink)  
Старый 27.02.2013, 11:24
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Это один и тот же подход. Просто в конструкторе нужно назначать свойства экземпляра (личные), а в прототипе - свойства прототипа (обычно методы). Почитай хотя бы http://learn.javascript.ru/prototype
Ответить с цитированием
  #18 (permalink)  
Старый 27.02.2013, 12:05
Аспирант
Отправить личное сообщение для Василий Б. Посмотреть профиль Найти все сообщения от Василий Б.
 
Регистрация: 01.03.2010
Сообщений: 44

danik.js,
как из можно назвать личными, если
function Base(){
	this.f = function(){alert('Base::f')}
};

function Parent(){}
Parent.prototype = new Base();

(new Parent()).f();

метол f доступен в Parent! Не могу понять почему.. метод f - это свойство объекта Parent, а не прототипа Base?
Ответить с цитированием
  #19 (permalink)  
Старый 27.02.2013, 12:16
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Под "личными" я не имел ввиду private. Я имел ввиду принадлежащие экземпляру.
Сообщение от Василий Б.
метол f доступен в Parent! Не могу понять почему.. метод f - это свойство объекта Parent, а не прототипа Base?
Ты явно не читал материал по ссылке.
Ответить с цитированием
  #20 (permalink)  
Старый 27.02.2013, 13:04
Аспирант
Отправить личное сообщение для Василий Б. Посмотреть профиль Найти все сообщения от Василий Б.
 
Регистрация: 01.03.2010
Сообщений: 44

danik.js,
да читал я материал, читал! Там написано следующее:
Цитата:
При создании объекта через new, в его прототип __proto__ записывается ссылка из prototype функции-конструктора.
и
Цитата:
Если один объект, например, rabbit, имеет специальную ссылку __proto__ на другой объект animal, то все свойства, которые ищутся в rabbit, будут затем искаться в animal.
Это понятно.
Свойства ищутся в прототипе объекта.

Правильно ли я понимаю, что только при использовании new в дочерний объект подтягиваются ВСЕ свойства объекта-прототипа?

Base = function(){};
Parent = function(){};
Parent.prototype = new Base();

var o = new Parent();

Base.func_as_prop = function(){};
Base.prototype.func_in_proto = function(){};

console.log(o.func_as_prop); // undefined - в объекте o нет свойства, т.к. оно не  было подтянуто конструктором
console.log(o.func_in_proto); // function

console.log(Base.func_as_prop); // function
console.log(Base.func_in_proto); // почему undefined? почему не ищет в своем прототипе?

Последний раз редактировалось Василий Б., 27.02.2013 в 13:11.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск