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

devote 10.04.2012 06:25

Использование классов в JavaScript
 
Эмуляция классов в JavaScript

Библиотека дает писать код с возможностями классового программирования. В JavaScript нет классов, но есть прототипы. Собственно используя возможности языка, я попытался реализовать некую обертку, которая более или менее приближено показывает как можно использовать классовое программирование на языке JavaScript.

Возможности библиотеки на мой взгляд вполне адекватны, поэтому при желании можно на ее основе построить огромный проект. Скорость работы кода с использованием данной библиотеки в целом не падает. Она старается максимально оптимизировать структуру классов. Библиотека работает во всех нынешних браузерах, даже в таком браузере как IE7, возможно даже в IE6 (Но я этого не проверял).

Методы:

Класс в текущем контексте
Class(Object/Function classStructure) : Function
// Объект в качестве аргумента
var MyClass = Class({
    method: function() {
    }
});
var instanceMyClass = new MyClass;
instanceMyClass.method();

// Функция для инкапсуляции в качестве аргумента
var MyClass = Class(function() {
    // инкапсуляция для каждого экземпляра своя
    var privateVariable = null;
    return {
        method: function() {
            return privateVariable;
        }
    }
});
var instanceMyClass = new MyClass;
instanceMyClass.method();
Класс в указанном пространстве имен
Class(String className, Object/Function classStructure) : Function
// Глобальное пространство имени
Class("MyClass", {
    ...
});
var instanceMyClass = new MyClass;

// пространство имени NS
Class("NS.MyClass", {
    ...
});
var instanceMyClass = new NS.MyClass;
Класc с наследованием
Class([String className,] Function parent, Object/Function classStructure) : Function
Class("ParentClass", {
    methodOfParent: function() {
        // ...
    }
});

// создаем класс наследуемый от ParentClass
var MyClass = Class(ParentClass, {
    ...
});
var instanceMyClass = new MyClass;
instanceMyClass.methodOfParent(); // Метод получим из класса ParentClass

// или
Class("MyClass", ParentClass, {
    ...
});
var instanceMyClass = new MyClass;
instanceMyClass.methodOfParent(); // Метод получим из класса ParentClass
Класc с множественным наследованием
Class(String className, String extends, Object/Function classStructure) : Function
Class("ParentClass1", {
    methodOfParent1: function() {
        // ...
    }
});
Class("ParentClass2", {
    methodOfParent2: function() {
        // ...
    }
});

Class("MyClass", "ParentClass1, ParentClass2", {
    ...
});
var instanceMyClass = new MyClass;
instanceMyClass.methodOfParent1(); // Метод получим из класса ParentClass1
instanceMyClass.methodOfParent2(); // Метод получим из класса ParentClass2

Другие вариации и методы
Class([String className, ][Object options, ][Object/Function classStructure]) : Function
Все параметры являются не обязательными.

Параметры:
  • className: String
    Параметр задает имя класса в контексте который мы укажем, поддерживается любое пространство имени, разделяя их точкой.
  • options: Object
    Этот параметр задает начальные опции для класса, такие как контекст в котором будет создан класс, наследники и статические свойства, подробнее о них я расскажу позже.
  • classStructure: Object/Function
    Параметр задает структуру класса, объект с вашими свойствами, методами. Разрешено указывать функцию в качестве аргумента, которая будет возвращать построенную структуру класса, это иногда удобно, когда например нужно использовать приватные методы/свойства.
Все параметры являются не обязательными, а значит вы можете пропустить тот или иной параметр, к примеру не указывать имя класса и начинать описывать опции или структуру класса, при этом опущенный параметр не нужно чем то закрывать, просто вместо него пишите то что идет за ним.
Возвращаемое значение : Function
Возвращает ссылку на конструктор созданного класса
Class.instanceOf( Object object, Function constructor ) : Boolean
Проверяет принадлежность объекта к указанному классу, простыми словами проверяет является ли объект наследником класса.

Параметры:
  • object: Object
    Объект, экземпляр класса, который будет проверяться на принадлежность к указанному классу.
  • constructor: Function
    Ссылка на класс, который будет проверятся является ли он потомком указанного объекта в первом параметре.
Возвращаемое значение : Boolean
Метод вернет true если объект является наследником класса, в противном случае вернет false
Class.imports( String/String[] url [, Function onLoad [, Function onError ]] )
Метод импортирует и исполняет .js файлы, поддерживает как синхронную, так и асинхронную загрузку.

Параметры:
  • url: String/String[]
    Параметр поддерживает два типа входных данных, это строку или массив строк. В качестве строк выступают ссылки на файлы которые будут импортированы.
  • onLoad: Function - Не обязательный
    Параметр принимает функцию, которая будет вызвана по окончании загрузки всех указанных файлов. Если этот параметр не задан, будет выполнятся синхронный режим загрузки.
  • onError: Function - Не обязательный
    Параметр принимает функцию, которая будет вызвана при возникновении ошибки во время загрузки файлов, если эта функция вернет значение true, то загрузка остальных файлов будет продолжена.

Использование:

Использование библиотеки очень простое, и немногим схожа с объявлениями классов например в PHP
Код в PHP:
class Foo {
    // структура класса
}
Код в JavaScript
Class( "Foo", {
    // структура класса
});
Как видите, сходство достаточно близкое. Я не стал придумывать что-то новое и попытался реализовать эмуляцию классов схожую к привычной в классовом программировании.

Сейчас я немного расскажу о дополнительных параметрах, которые указываются в объекте options, описанный ранее в описании метода Class.
  • context: Object
    Параметр указывает конструктору классов, о том куда нужно разместить ссылку на объявленный класс. По умолчанию все объявленные классы, попадают в глобальное пространство window, в нем создается свойство с именем класса, имеющее ссылку на объявленный класс
  • extend: String/Function
    Параметр указывает о том от кого нужно унаследовать свойства. Параметр может быть двух типов.
    String - строка содержащая имя класса от которого будет унаследован объявленный класс, поиск класса родителя будет произведен в том же контексте в котором объявляется класс.
    Function - ссылка на конструктор класса, может находится совершенно в любом пространстве имен.
  • mixins: String/Function/String[]/Function[]
    Дает возможность организовать множественное наследование. Множественное наследование ни чем не ограничено от обычного наследования.
    Значение может иметь как строку с именем наследуемого класса, так и конструктор наследуемого класса. Так же параметр может иметь тип массива, в котором будут указанны по порядку строки или конструкторы наследуемых классов.
  • statics: Object
    Объект со статическими свойствами
Определение класса:
Class("SimpleClass", {
    // свойства класса
    ...
});

Конструкторы:

конструкторы есть двух типов, первый это метод имеющий такое же имя как имя класса:
Class("SimpleClass", {
    SimpleClass: function() {
        // будет вызван при создании экземпляра
    }
});
Второй вариант имеет всеми привычное имя: constructor, часто удобен при создании анонимных класов:
var SimpleClass = Class({
    constructor: function() {
        // будет вызван при создании экземпляра
    }
});


... описал бы больше, но тут лимит в 10000 символов на пост(((

Типы и различия в файлах библиотек:
class.js        - Полная версия библиотеки, включает в себя все что описано выше.
class.min.js    - Сжатая с помощью GCC.
Скачать все это можно на GitHub: https://github.com/devote/jsClasses

Pavel M. 10.04.2012 09:02

не знал, что setter's/getter's можно реализовать для старых ie через vbscript, спасибо

FINoM 10.04.2012 18:04

Чтобы не было столько минусов, нужно было написать «В JAVASCRIPT НЕТ КЛАССОВ, НИЖЕ ИЗЛОЖЕН ОДИН ИЗ СПОСОБОВ ЭМУЛЯЦИИ»

devote 10.04.2012 18:31

Цитата:

Сообщение от FINoM
Чтобы не было столько минусов

Ну меня собственно не расстраивают минусы. Если людям нравится жать кнопку "-" то пусть жмут на здоровье, а те кто нормально прочтут статью и поймут в чем профит. Просто добавят в избранное или просто пройдут мимо.

Минусы как правило ставят те кто читал подобные статьи, но не удосужился прочесть эту. А просто включив опцию "стада" в голове пошел ставить минус. Уж таковы реалия и с этим ничего не поделаешь.

PS. Писать статьи я не мастак, а точнее не писал никогда. От того и недопонимание у некоторых людей возникают.

melky 10.04.2012 18:34

я обхожусь встроенными средствами. классы - на любителя.

Цитата:

Сообщение от Pavel M. (Сообщение 168035)
не знал, что setter's/getter's можно реализовать для старых ie через vbscript, спасибо

то же самое.

devote, не поделитесь секретом ?

FINoM 10.04.2012 18:36

Честно сказать, лучше бы сделал либу для поддержки какой-нибудь фигни из ES.next.
Цитата:

Сообщение от devote
От того и недопонимание у некоторых людей возникают.

Это не отменяет того факта, что, в первую очередь, нужно вводить людей в тему, пускай и кратко. Сочинения, ведь, в школе писал.

FINoM 10.04.2012 18:36

Цитата:

Сообщение от melky
devote, не поделитесь секретом ?

http://webreflection.blogspot.com/20...6-7-and-8.html

devote 10.04.2012 18:39

Цитата:

Сообщение от melky
devote, не поделитесь секретом ?

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

Сообщение от FINoM
Сочинения, ведь, в школе писал.

прогуливал :D литература/русский для меня темный лес всегда были.

FINoM 10.04.2012 18:42

Цитата:

Сообщение от devote
литература/русский для меня темный лес всегда были.

То же самое, но есть очень простое правило любой публикации: введение, суть, заключение.

melky 10.04.2012 18:53

Цитата:

Сообщение от FINoM (Сообщение 168160)

логичней бы было кинуть ссылку сразу на код

devote 15.04.2012 12:32

закинул на гитхаб совершенно новую реализацию, с исправлением множества багов, с добавлением доп возможностей по ходу понимания VBScript если кому надо качаем на гитхабе https://github.com/devote/jsClasses фоловится там не забываем

devote 19.07.2012 02:41

обновил версию если оно вообще кому-то надо, добавил autoload и исправил баг в ИЕ, GCC портил код для ИЕ..

devote 20.07.2012 14:15

я конечно понимаю что всем похуй... но:

я снова обновил репу, добавил метод Class.imports теперь можно легко подгружать нужные модули:
// синхронная загрузка
Class.imports( "somescript.js" );

// синхронная мультизагрузка
Class.imports( [ "somescript.js", "somescript2.js" ] );

// асинхронная загрузка
Class.imports( "somescript.js", function() {
    // some code
});

// асинхронная мультизагрузка
Class.imports( [ "somescript.js", "somescript2.js" ], function() {
    // some code
});

devote 21.07.2012 03:10

исправил еще один косячок, как выяснилось ИЕ ниже 9-й версии загружает и исполняет скрипты быстрее через XHR нежели через обычную вставку тега script на страницу. Остальные браузеры быстрее это делают через тег script.

Ну и добавил демо пример в первый топик.

FINoM 21.07.2012 16:35

Цитата:

Сообщение от devote
я конечно понимаю что всем похуй...

Сам-то используешь в своих проектах?

devote 21.07.2012 17:02

Цитата:

Сообщение от FINoM
Сам-то используешь в своих проектах?

для работы пока нет, но пишу на ней чудотворный элексир :D потом представлю во внимание, когда это превратится во что-то более и менее приличное.

x-yuri 22.07.2012 15:58

Цитата:

Сообщение от devote
я конечно понимаю что всем похуй... но:

Чего так пессимистично? Интересная штука, правда не то чтобы жизненно необходимая.

Вот здесь немножко передернуло: "Есть тут свои тонкости, конечно же нет возможности создания интерфейсов, абстракции и прочих полноценных прелестей ООП."

devote 22.07.2012 16:20

Цитата:

Сообщение от x-yuri
Чего так пессимистично?

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

Цитата:

Сообщение от x-yuri
Интересная штука, правда не то чтобы жизненно необходимая.

Ну я рад что хоть кого-то заинтересовало :)

FINoM 22.07.2012 16:26

Цитата:

Сообщение от devote
Ну я рад что хоть кого-то заинтересовало

Мне лично тоже интересно, но, блин, не понимаю, где это применить.

x-yuri 22.07.2012 21:04

Сначала удивился, а потом понял, что уже не помню насколько удобно использовать классы в native js, в частности наследование. По поводу __get/__set, можно проксировать методы/свойства (или агрегировать объекты). Например, у тебя есть коллекция, которая все неизвестные ей методы перенаправляет на свои элементы:
$$('.myClass').addEvent(...).

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.
Вот пример сгенерированной доки.

devote 23.07.2012 15:12

B~Vladi,
вот спасибо добрый человек. Почитаю на досуге что к чему, я так понимаю IDE нужно для этого дела то.. Видимо придется поставить.

B~Vladi 23.07.2012 15:19

Цитата:

Сообщение от devote
я так понимаю IDE нужно для этого дела

Нет, не нужно. IDE даст тебе только автокомплит (как в коде, так и при написании jsdoc), а генерировать саму доку нужно отдельной утилитой, ссылку на которую я тебе давал выше. Если вообще захочешь генерировать.

devote 23.07.2012 15:20

а отлично, покумекаю над этим на досуге.. Доку то надо начирикать какую то.

x-yuri 23.07.2012 17:03

Цитата:

Сообщение от devote
Есть тут свои тонкости, конечно же нет возможности создания интерфейсов, абстракции и прочих полноценных прелестей ООП.

Цитата:

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

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

Цитата:

Сообщение от devote
честно говоря над методом Class.autoload нужно еще поработать, мне конечно не совсем пока нравится как это работает. Поэтому в будущих версия этот метод возможно претерпит изменения.

Цитата:

Сообщение от devote
насчет обработки ошибок (Class.imports) тоже вполне возможно будут изменения, но пока не решил как улучшить и т.д.

что не нравится?

Цитата:

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

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

Цитата:

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

Цитата:

Сообщение от devote
аж 12 вариантов:

Поддерживаю, слишком много. Можно было бы вынести дополнительные свойства в отдельный аргумент, в результате у них появится имя:
Class('MyClass', {
    myMethod: function() {...},
    ...
}, {context: '...', staticData: {...}});

т.е. такая сигнатура: Class(name, data, options)

И по поводу extends/implements/include (наследование), их можно туда же засунуть. Или прямо в data, зарезервивовав для служебных целей, например, двойное подчеркивание:
Class('MyClass', {
    __extends: 'MyBaseClass',
    __implements: 'MyMixin',
    __construct: function() {...},
    myMethod: function() {...}
});

B~Vladi 23.07.2012 21:07

Цитата:

Сообщение от x-yuri
Правильнее было бы не называть это, чтобы можно было самому решать, где это будет пространством имен, а где классом.

Нужно просто правильно сформулировать это в доках.

devote 24.07.2012 04:46

Цитата:

Сообщение от x-yuri
Создается впечатление, что автор считает классовое ООП рассово верным, чем может обидеть религиозные чувства сторонников противоположной позиции, случайно наткнувшихся на этот текст...

ясно, перепишу позже иначе.

Цитата:

Сообщение от x-yuri
что не нравится?

ну то что autoload можно назначить лишь раз для всех скриптов, и входные параметры возможно сменю.. Нужно наверно добавить во входной параметр и имя класса который пытается найти нужный ему класс.. Хотя над этим еще подумаю. Насчет imports пока сложно сказать что не так, но явно что-то не так. :)

Цитата:

Сообщение от x-yuri
Поддерживаю, слишком много. Можно было бы вынести дополнительные свойства в отдельный аргумент, в результате у них появится имя:

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

Цитата:

Сообщение от x-yuri
Или прямо в data,

Насчет implments я его не реализовывал, пока не вижу в нем необходимости, множественное наследование не так часто нужно поэтому над этим еще нужно покумекать.

При всем этом я писал из расчета скорости работы, если я напишу так как вы предлагаете во втором варианте, тоесть прямо в data это приведет к тому что при создании экземпляра нужно будет каждый раз разбирать все эти параметры, что приведет к занижению производительности. Хоть она и не заметна будет, но для большого кода/проектов это значительные потери. В моей же реализации, все манипуляции с параметрами происходят во время объявления класса, далее уже при создании экземпляров, никакие параметры не разбираются.
Допустим:
Class("Foo", Parent, { // вот именно в этот момент идет разбор параметров
    // some code
});

// никакого разбора не происходит, но ищутся такие
// свойства как setters/getters затем складываются в
// специальный стек
var a = new Foo();

// при втором обращении, уже ничего вообще не делается
// а все сеттеры/геттеры берутся из стека, что увеличивает
// скорость работы конструктора.
var b = new Foo();

Цитата:

Сообщение от B~Vladi
Нужно просто правильно сформулировать это в доках.

Насчет доков я все же посмотрел JSDoc и попробовал, честно скажу паршивая это штука. Совсем не понятно делает доку. Без пива сложно понять. Хотя дело привычки конечно. Но и описании в коде под него нужно хорошо заточить, что бы он все подряд в доку не совал. Как это произошло у меня, все приватные и внутренние методы сунул в доку, что не есть гуд.

B~Vladi 24.07.2012 09:54

Цитата:

Сообщение от devote
все приватные и внутренние методы сунул в доку, что не есть гуд.

Юзай @private или @ignore.

Цитата:

Сообщение от devote
Совсем не понятно делает доку.

Если разобраться, то всё становится понятным.

devote 24.07.2012 10:37

Цитата:

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

ну дык я и говорю, без пива не разберешь :) А так да, время лечит.

x-yuri 24.07.2012 15:12

Цитата:

Сообщение от devote
ну то что autoload можно назначить лишь раз для всех скриптов, и входные параметры возможно сменю.. Нужно наверно добавить во входной параметр и имя класса который пытается найти нужный ему класс.. Хотя над этим еще подумаю.

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

Цитата:

Сообщение от devote
А вот такой вариант я почему-то считаю сложным, не знаю возможно для любителей JS он удобен и т.д. Но его тоже нужно будет изучать и так же получится не один, не два не три варианта а много, где нужно будет знать еще какие-то тонкости. Но тем не менее я подумаю над этим, возможно что-то придумаю.

Что ж в нем сложного-то? Использование объекта (ассоц. массива) вместо перечисления параметров через запятую? В твоём варианта рассчет идет на очевидность, с целью сэкономить на "назывании параметров". Экономия очень сомнительная на мой взгляд. Чем больше параметров, тем сомнительнее. Так почему бы не расслабиться и не использовать мой вариант? А твой подход использовать, в более простых случаях? Кстати, я бы назвал его jQuery-подходом.

Цитата:

Сообщение от devote
При всем этом я писал из расчета скорости работы, если я напишу так как вы предлагаете во втором варианте, тоесть прямо в data это приведет к тому что при создании экземпляра нужно будет каждый раз разбирать все эти параметры, что приведет к занижению производительности. Хоть она и не заметна будет, но для большого кода/проектов это значительные потери. В моей же реализации, все манипуляции с параметрами происходят во время объявления класса, далее уже при создании экземпляров, никакие параметры не разбираются.

Во-первых, кеширование никто не отменял. Во-вторых, это ваше классовое ООП странновато смотрится в прототипно-ориентированном ЯП. Альтернатива: mixin, inherit. Разве этого не достаточно? :) На фоне альтернативного варианта твоя библиотека выглядит ненужным усложнением (в первую очередь интересны __get/__set и autoload, ну и imports), и тут мне в очередной раз приходит в голову мысль, что большинство проблем с производительностью связаны с неоправданно высокими требованиями (ненужными усложнениями)...

devote 24.07.2012 15:28

Цитата:

Сообщение от x-yuri
Да, несколько раз было бы удобнее. По поводу параметров, не знаю, зачем может понадобиться что-то кроме имени класса, который надо подгрузить. Хотя дополнительная информация наверное не помешает.

вот и я о том же.

Цитата:

Сообщение от x-yuri
Что ж в нем сложного-то? Использование объекта (ассоц. массива) вместо перечисления параметров через запятую?

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

Цитата:

Сообщение от x-yuri
Во-вторых, это ваше классовое ООП странновато смотрится в прототипно-ориентированном ЯП

Никто и не утверждает обратного.


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