Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Использование классов в JavaScript (https://javascript.ru/forum/project/27339-ispolzovanie-klassov-v-javascript.html)

devote 22.07.2012 21:27

Цитата:

Сообщение от x-yuri
Вот здесь немножко передернуло:

хм.. что-то не так написал? могу исправить если я в чем-то ошибаюсь.

devote 23.07.2012 08:03

Очередное обновление.

Немного оптимизирован код, исправлены пару мелких багов. Добавлены возможности. Теперь можно создавать классы любой вложенности, например:
Class("ui.fx.Animation", {
    // ...
})
данный класс будет доступен как ui.fx.Animation, так же можно и расширять классы:
Class("ui.Button extends ui.fx.Animation", {
    // ...
})
создастся класс ui.Button с унаследованными свойствами от ui.fx.Animation.

Следующее нововведение это возможность объявлять классы совершенно в любом порядке. То-есть ранее нужно было учитывать порядок. Например нужно было перед объявлением класса ui.Button объявить класс ui.fx.Animation. Но теперь можно сначала объявить класс ui.Button а уже потом где-то ниже или подключить позже класс ui.fx.Animation, при этом все будет работать корректно. Наглядный пример:
<script type="text/javascript" src="https://github.com/devote/jsClasses/raw/master/core.class.min.js"></script>
<script>
Class( "Foo extends Bar", {
    test: function() {
        return this.name;
    }
});

Class( "Bar", {
    name: "Vasya"
});

alert( (new Foo()).test() );
</script>
Есть возможность отключить кеширование файлов при использовании Class.imports, достаточно где-то в начале кода установить значение:
Class.imports.disableCaching = true;
и все загружаемые файлы всегда будут вновь загружаться с сервера, это удобно для отладки кода.

Так же можно перехватить ошибку загружаемого модуля, допустим при создании экземпляра класса не удалось найти класс от которого нужно наследоваться, в этом случае сработает событие Class.autoload, пример:
<script type="text/javascript" src="https://github.com/devote/jsClasses/raw/master/core.class.min.js"></script>
<script>
Class( "Foo extends Bar", {
    test: function() {
        return this.name;
    }
});

Class.autoload = function( className ) {

    alert( "Не найдет класс " + className + " в контексте " + this );

    // тут можно вернуть конструктор другого класса например:
    return Class({
        name: "Petya"
    });

    // или же просто загрузить нужный класс, но в синхронном режиме
    // либо ничего не возвращать, что приведет к останову скрипта
}

alert( (new Foo()).test() );
</script>
честно говоря над методом Class.autoload нужно еще поработать, мне конечно не совсем пока нравится как это работает. Поэтому в будущих версия этот метод возможно претерпит изменения.

Так же забыл сообщить о том что при использовании метода Class.imports можно перехватить ошибку загрузки, пример:
Class.imports([
    "somefile.js",
    "somefile2.js"
], function(){
    // succes loaded
}, function( status, url ) {
    alert( "Ошибка загрузки файла: " + url + ", статус ошибки: " + status );
    // если вернуть значение true, то загрузка остальных файлов продолжится не смотря на ошибку.
    // В противном случае загрузка файлов не будет продолжена.
})
насчет обработки ошибок тоже вполне возможно будут изменения, но пока не решил как улучшить и т.д.

Если есть идеи/пожелания/критика, с удовольствием выслушаю.

Спасибо.

B~Vladi 23.07.2012 13:44

Цитата:

Сообщение от devote
классы любой вложенности, например:
Class("ui.fx.Animation", {
    // ...
})

Правильнее было бы назвать это пространством имён.

Цитата:

Сообщение от devote
Class("ui.Button extends ui.fx.Animation", {
    // ...
})

создастся класс Class.ui.Button с унаследованными свойствами от Class.ui.fx.Animation.

Что-то ты намудрил, не лучше ли как-то так?
Class("ui.Button", {
    // ...
}).extend(Class.ui.fx.Animation);


Пожалусто :)

devote 23.07.2012 13:56

Цитата:

Сообщение от B~Vladi
Правильнее было бы назвать это пространством имён.

точно! :)
Цитата:

Сообщение от B~Vladi
не лучше ли как-то так?

хм... мысль интересная, но вот никак не могу понять как это реализовать. Ведь наследование происходить не во время объявления класса, а при создании экземпляра.. То-есть создаем класс
Class("ui.Button extends ui.fx.Animation", {
    // ...
});
в этом случае класс лишь объявлен, и не имеет экземпляров, а вот когда мы вызываем:
new ui.Button();
в этом случае происходит наследование, то-есть вызывается создание экземпляра родительского класса. Не раньше. И если делать так как предлагаешь, то я понятия не имею как это реализовать.

Хм... Хотя конечно мысль одна есть, попробую над ней подумать.

devote 23.07.2012 14:05

B~Vladi,
да кстати я не упоминал наверно, но можно еще и так создавать классы:
Class("ui.Button", ui.fx.Animation, {
    // ...
});
а вообще внутри библиотеки указаны примеры создания:
/*
	*  Class( context, "className", parentClass, staticObject, classStructure )
	*  Class( context, "className", parentClass, classStructure )
	*  Class( context, "className", staticObject, classStructure )
	*  Class( context, "className", classStructure )
	*
	*  Class( "className", parentClass, staticObject, classStructure )
	*  Class( "className", parentClass, classStructure )
	*  Class( "className", staticObject, classStructure )
	*  Class( "className", classStructure )
	*
	*  Class( parentClass, staticObject, classStructure )
	*  Class( parentClass, classStructure )
	*  Class( staticObject, classStructure )
	*  Class( classStructure )
	*/
аж 12 вариантов:
// первый параметр контекст в котором будет создан класс
// второй имя класса
// третий конструктор класса от которого хотим наследоваться
// четвертый объект со статическими свойствами, которые будут доступны без создания экземпляра, через Foo.STATIC_PARAM
// пятый, собственно сам класс
Class( window, "Foo", Bar, {
    "STATIC_PARAM": "hello"
}, {
    constructor: function() {
    }
});

// все что выше но без статического объекта
Class( window, "Foo", Bar, {
    constructor: function() {
    }
});

// все что выше но без наследования, и со статическими параметрами
Class( window, "Foo", {
    "STATIC_PARAM": "hello"
}, {
    constructor: function() {
    }
});

// все что выше но без наследования и без статических параметров
Class( window, "Foo", {
    constructor: function() {
    }
});
остальное описывать не буду, по названиям должно быть понятно.

B~Vladi 23.07.2012 14:11

Цитата:

Сообщение от devote
да кстати я не упоминал наверно, но можно еще и так создавать классы:

Ну или так, да. А то какой-то свой язык создаешь, восприниматься будет не так легко, как с параметром.

Цитата:

Сообщение от devote
примеры создания

Ух, как-то сложновато имхо. Это надо оптимизировать.

Цитата:

Сообщение от FINoM
не понимаю, где это применить.

Думается мне, что не зря devote приводит примеры с именами классов UI-элементов. Я и сам так же когда-то для scalaxy интерфейс генерировал, типо свой ExtJS. Удобно. Только я не заморачивался с наследованием.

devote 23.07.2012 14:20

Цитата:

Сообщение от B~Vladi
Ух, как-то сложновато имхо. Это надо оптимизировать.

хм.. разве сложно? на мой взгляд гибко, выбирай любой удобный вариант. А что самое важное, что это не тормозит работу скриптов. Ведь объявляются классы лишь при загрузке скриптов, то-есть один раз. А далее уже обычное создание экземпляров, где уже не происходит никаких манипуляций с этими параметрами.

B~Vladi 23.07.2012 14:46

Цитата:

Сообщение от devote
выбирай любой удобный вариант

Я к тому что вариантов получилось многовато => сложнее запомнить => постоянно придется смотреть исходник или доку.

На крайняк напиши JSDoc, адекватные IDE смогут подсказку показывать налету и не придется открывать исходники.

devote 23.07.2012 14:49

Цитата:

Сообщение от B~Vladi
На крайняк напиши JSDoc, адекватные IDE смогут подсказку показывать налету и не придется открывать исходники.

я понятия не имею как его писать.. не писал такого.. Где об этом читать и что юзать надо? Яж не пользуюсь IDE у меня все по старинке, синий экран, светло-серые буквы :p

B~Vladi 23.07.2012 15:03

Цитата:

Сообщение от devote
Яж не пользуюсь IDE у меня все по старинке

Мде.

JSDoc - версия JavaDoc для JS.

Сайт проекта реализации на Java.

В твоём случае нужно заменить комментарий на:
/*
* @name Создатель НАСТОЯЩИХ классов в JS!!11 0_o
* @example
* Class( context, "className", parentClass, staticObject, classStructure )
* Class( context, "className", parentClass, classStructure )
* Class( context, "className", staticObject, classStructure )
* Class( context, "className", classStructure )
*
* Class( "className", parentClass, staticObject, classStructure )
* Class( "className", parentClass, classStructure )
* Class( "className", staticObject, classStructure )
* Class( "className", classStructure )
*
* Class( parentClass, staticObject, classStructure )
* Class( parentClass, classStructure )
* Class( staticObject, classStructure )
* Class( classStructure )
*/


В IDE от JetBrains доку можно смотреть по Ctrl+Q.
Вот пример сгенерированной доки.


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