Очередное обновление.
Добавлена возможность множественного наследования, так же внесены изменения во входные параметры. Так же добавлен параметр Class.defaultContext в который вы можете указать объект, куда по умолчанию будут складываться все созданные классы, у которых явно не указан контекст. Объявлять классы как обычно можно: Class("Foo", { // code });если нужны указать дополнительные параметры, это теперь можно сделать так: Class("Foo", { // контекст в котором будет создан класс context: window, // строка/конструктор от которого будем наследоваться extends: "Bar", // строка/конструктор или список строк/конструкторов, из которых будут получены дополнительные свойства implements: [ "IBase", "IPersistent" ], // статические параметры static: { STATIC_PARAM: 1, STATIC_CONST: "lala" } }, { // code }); Пример: <script type="text/javascript" src="https://github.com/devote/jsClasses/raw/master/core.class.min.js"></script> <script type="text/javascript"> Class("Foo", { foo: function(){ alert( this.__class__.className ); }, "get name": function() { return "this Foo name"; } }); Class("Bar", { bar: function(){ alert( this.__class__.className ); }, "get name": function() { return "this Bar name"; } }); Class("Tre", Foo, { trefoo: function(){ alert( this.__class__.className ); } }); Class("Mix", { extends: "Tre", implements: "Bar" }, { }); var a = new Mix(); a.foo(); a.bar(); a.trefoo(); alert( a.name ); </script>или так: <script type="text/javascript" src="https://github.com/devote/jsClasses/raw/master/core.class.min.js"></script> <script type="text/javascript"> Class("Foo", { foo: function(){ alert( this.__class__.className ); }, "get name": function() { return "this Foo name"; } }); Class("Bar", { bar: function(){ alert( this.__class__.className ); }, "get name": function() { return "this Bar name"; } }); Class("Tre extends Foo", { trefoo: function(){ alert( this.__class__.className ); } }); Class("Mix extends Tre, Bar", { }); var a = new Mix(); a.foo(); a.bar(); a.trefoo(); alert( a.name ); // или Class("Mix2", "Tre, Bar", { }); var a = new Mix2(); a.foo(); a.bar(); a.trefoo(); alert( a.name ); </script> |
Почему бы не сделать так:
Class("Foo", { // контекст в котором будет создан класс __context: window, // строка/конструктор от которого будем наследоваться __extends: Class.Bar, // строка/конструктор или список строк/конструкторов, из которых будут получены дополнительные свойства __implements: [ Class.IBase, Class.IPersistent ] }, { // code }); Таким образом можно будет передавать любой конструктор... |
Цитата:
<script type="text/javascript" src="https://github.com/devote/jsClasses/raw/master/core.class.min.js"></script> <script type="text/javascript"> Class("IBase", { someField: 100 }); Class("IPersistent", { key: "persistentKey" }); Class("Bar", { bar: function() { alert( this.__class__.className ); } }); Class("Foo", { // контекст в котором будет создан класс context: window, // строка/конструктор от которого будем наследоваться extends: Bar, // строка/конструктор или список строк/конструкторов, из которых будут получены дополнительные свойства implements: [ IBase, IPersistent ] }, { constructor: function() { alert( "Foo constructor execute" ); } }); var a = new Foo(); a.bar(); alert( a.someField ); alert( a.key ); </script> |
Цитата:
|
А теперь получается, что первый аргумент - имя класса, третий - прототип, а второй - свалка для всего остального, отчасти это статические свойства, отчасти параметры для функции. Я бы тогда поместил статические свойства в отдельный параметр и убрал двойное подчеркивание:
Class("Foo", { context: window, extends: "Bar", implements: [ "IBase", "IPersistent" ], static: { STATIC_PARAM: 1, STATIC_CONST: "lala"} }, { // code }); Кстати, можно как-то в прототипе указать конструктор? Или надо для этого указывать функцию вместо объекта? Ну и, предыдущий интерфейс остался же? Я считаю, не стоит стремится всем угодить. P.S. Я не очень старался, но я не въехал в код угадывания какой входной параметр что обозначает. ;) |
Цитата:
Class("Foo", { context: window, extends: "Bar", implements: [ "IBase", "IPersistent" ], }, { // это и есть конструктор, который сработает при создании экземпляра класса constructor: function( test ) { alert( test ); } }); new Foo( "Hello!" );можно писать и так: Class("Foo", { context: window, extends: "Bar", implements: [ "IBase", "IPersistent" ], }, function() { // тут можно поместить приватные переменные, для каждого экземпляра они свои собственные. var private = "tarata"; return { // это и есть конструктор, который сработает при создании экземпляра класса constructor: function( test ) { alert( test ); } } }); new Foo( "Hello!" ); Цитата:
Цитата:
Первый Имя, Второй свалка, Третий объект класса либо Первый Имя, Второй объект класса |
Цитата:
|
Цитата:
|
Цитата:
Первый Имя, Второй объект класса, Третий свалка (необязательный параметр) |
Цитата:
|
Цитата:
Тогда следующее тролль-предложение: объединить доп. параметры с "прототипом". Т.к. это и не совсем прототип, из-за свойства constructor, то и доп. параметры вполне неплохо туда впишутся. |
Цитата:
Class("Foo", function() { // функция врапер var private = "1"; return { __extends: "Bar", constructor: function() { } } });вот параметр __extends мне не будет доступен в момент объявления класса, так как он будет завернут в функцию, а что бы его получить придется инициализировать приватные параметры. То-есть вызвать функции врапер. что не есть гуд, потому как я вызываю его лишь когда создают экземпляр |
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
Цитата:
1. Ты сам создаешь конструктор, который вызывает сначала функцию-обертку, а потом конструктор указанный пользователем? Другими словами функция-обертка - часть конструктора? 2. Попытавшись просмотреть код конструктора, я получу код твоей функции, а не той, которую я передал в Class? |
Цитата:
Цитата:
Цитата:
|
Очередное обновление, сделал так как предложил x-yuri,
Class("Foo", { context: window, extends: "Bar", implements: [ "IBase", "IPersistent" ], static: { STATIC_PARAM: 1, STATIC_CONST: "lala" } }, { // code }); |
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
Но это мое ИМХО, и если все же приватные свойства были бы не к чему, их бы не использовали бы нигде. |
Есть такая штука как, назовём это, приватность по соглашению:
Class('MyClass', { myPublicMethod: function() {...}, _myPrivateMethod: function() {...} Так что никто спрашивать не будет. А по поводу защиты от случайной ошибки, то выглядит она сомнительно, непонятно, насколько часто она бы срабатывала. Цитата:
|
Всем снова привет!
Сегодня влил новую стабильную версию библиотеки. В новой версии были внесены некоторые изменения и нововведения. Что нового? 1. Была переработана система наследования, теперь множественное наследование это, все равно что обычное наследование. 2. Была введена отдельная инкапсуляция для аксессоров. 3. Теперь конструкторы можно называть именем класса. Что изменилось? 1. Теперь контекст классов по умолчанию всегда глобальный. 1. Теперь при обращении к аксессору не имеющего getter'а срабатывает исключение, то же самое и с setter'ом. Эти добавления и изменения заставили переписать систему построения наследования почти с нуля. Так же это сказалось на оптимизации, скорость построения классов увеличилась, размер кода остался почти без изменений (то есть мне удалось внести нововведения и изменения без огромного увеличения размера библиотеки). Примеры:
Основную документацию вы найдете в первом топике этой темы. На любые вопросы с большим удовольствием отвечу. Пожелания, выслушаю. Всем спасибо! Скачать как всегда тут: https://github.com/devote/jsClasses |
В пост выше, добавил рисунок структуры объекта, получившегося в отладчике Dragonfly.
|
Цитата:
|
x-yuri,
решил спустя пол года ответить на пост?))) |
ну ты ж вчера воскресил тему, вот я и наткнулся на твою фразу ;)
|
Цитата:
|
Снова всем привет!
Для тех кому не по
Все прочее как всегда в первом посте этого треда. |
Часовой пояс GMT +3, время: 09:00. |