All streams
Search
Write a publication
Pull to refresh
32
0
Dmitrii Pakhtinov @devote

User

Send message
А это не будет слишком громоздким? Или я возможно не так понимаю вашу задумку. Но как я понял это если будет 20 потомков, то что бы вызвать последнего потомка, нужно прописать целую цепь:
var q  = new Class.UI.button.Lala.Trata.TirTir.Q.W.E.R.T.Y.U.I.P.A.S.D.F.G.H();
По моему это немного не красиво, да и еще и не удобно. Хотя возможно вы имеете ввиду что то иное. И я просто вас не понял.
Согласен с вами, все начинается с маленького)
Вы правы, это сложное и серьезное направление. Но свою библиотеку я все же планирую использовать на практике. Для начала хочу попробовать на ней написать что-то не совсем серьезное, то-есть что-то небольшое, что бы посмотреть как пойдет. А там глядишь и до чего-то серьезного дело дойдет. Но пока об этом рано говорить.
Да я понимаю что в будущем JS обзаведется нативной возможностью создания классов, не даром в браузерах слова class, private, protected и т.д. уже сегодня являются зарезервированными, хотя браузеры и не ругаются при их использовании в иных случаях.

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

Вот насчет Class.UI.button.create() я не совсем понял что вы имеете ввиду. То-есть нужен метод который будет срабатывать до создания объектов, в котором будут указываться правила?
Я внес изменения в библиотеку, причем не только эти. Теперь немного иначе работает, не так как описанная выше, так же исправил кучу ошибок, добавил возможности, добавил ссылку на static.

Теперь работает иначе, примерно такой вид:
Class( "Factory", {

    // старый вариант, так же работает
    $accessor1: 0,
    $accessor2: 0,

    // сеттеры для универсальных свойств, указанных выше со знаком доллара
    __set: function( prop, value ) {
        //
    },

    // гкттер для универсальных свойств, указанных выше со знаком доллара
    __get: function( prop ) {
        //
    },


    // сеттер для свойства name
    "set name": function( value ) {
    },

    // геттер для свойства name
    "get name": function() {
    }
});

Теперь все классы по умолчанию создаются в контексте Class, то-есть наш класс Factory будет доступен через new Class.Factory()

Изменить контекст можно, так:
Class( window, "Factory", {} ); // создали в глобальном контексте

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

Но вот не знаю куда выложить новую версию, которая немного иная… Ибо статья описывает иную версию. Стоит ли менять статью!? Вот даже не знаю как быть.
Практической цели вовсе и не было, по большей части просто захотелось сделать возможность все же использовать возможности VB которые так никто и не пытался толком использовать. То-есть попытки разные были, но я пошел немного другим путем. Организация аксессоров в ИЕ старых версий имеет ряд ограничений, одно из них это отсутствие возможности добавления динамических свойств, то-есть VB не дает создать новое свойство если то не было объявлено явно.

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

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

PS. Статьи никогда не писал, это мой первый опыт так сказать. Я старался писать ее так как обычно сам предпочитаю читать, и я никогда лично сам не реагирую на статьи паникуя и тряся всем телом, выплевывая слюни в попытке рассказать автору статьи что он не прав. Для меня любая статья, в первую очередь просто статья, а если считаю ее не нужной, просто забываю о ней.
Ещё вопрос — что будет, если ваш код будет использоваться с 'use strict'?
Будет все хорошо, я проверял работу скрипта с установленным значением «use strict»;
Скажите без обид, вас подобные статьи/решения пугают? Или выводят из себя? Поймите, вас же никто не заставляет писать код иными способами, пишите так как писали и никто вас за это судить не будет. Но голословно утверждать словами «Не надо», не совсем корректно. Каждый для себя решает сам как ему готовить то или иное блюдо. Если вам статья не понравилась, проходите мимо. Если видите в статье глупость, тупость, незнание, флуд и т.д. Ставьте минус, если статья не глупа но вам она не по душе, просто читайте то что вам по душе.

Кому-то данная статья принесла пользу, уж точно не обратное. Либо пользу, либо ничего. Третьего ни как не может быть. Поэтому мысли «Не надо» оставьте при себе, или хотя бы дополняйте свои посты всем известным ИМХО.

ИМХО.
И поверьте, я далеко не новичок)
вот лог что я увидел запустив ваш пример:

[10.04.2012 19:26:01] JavaScript — localhost/
console.log
Qux.get
[10.04.2012 19:26:01] JavaScript — localhost/
console.log
Bar.get
[10.04.2012 19:26:01] JavaScript — localhost/
console.log
Foo.get
А вы проверьте и увидите что ее не будет… Поверьте этот вопрос я решал обдуманно. Зацикливания не будет, это я вам уверенно могу сказать.
Верно подмечено, именно по этой причине я и решился перенять решение из PHP. Так как оно мне показалось более изящным и маложрущим ресурсы.
Все же оба варианта имеют право на жизнь. Какой именно стоит реализовать, об этом надо подумать.
Хотя тут есть одна небольшая проблемка. Если родительский класс тоже реализует аксессоры, и они имеют одинаковые имена. Допустим:

classes.Class( "ButtonClass", {
    $accessors: {
        accessor1: {
            get: function (currentValue) {
                return currentValue + ': getter';
            },

            set: function (newValue) {
                return 'setter: ' + newValue;
            }
        }
    }
});

classes.Class( "SuperButtonClass extends ButtonClass", {
    
    property : 'foo',
    anothProp: 'bar',
    
    $accessors: {
        accessor1: {
            get: function (currentValue) {
                return currentValue + ': getter';
            },

            set: function (newValue) {
                return 'setter: ' + newValue;
            }
        },

        accessor2: {
            get: function (currentValue) {
                return currentValue + ': second getter';
            },

            set: function (newValue) {
                return 'second setter: ' + newValue;
            }
        }
    },
    
    method: function () {
        return Math.random() * 42;
    }
});

Как вызвать сеттер/геттер родительского класса? В моем случае это можно сделать так:
{
    $accessor1: 0,
    $accessor2: 0,
    set__: function( prop, val ) {

        this.parent.set__( prop, val );

        accessors[ prop ] && accessors[ prop ].call( this, val, true );
    },
    get__: function( prop ) {

        if ( accessors[ prop ] ) {

            return accessors[ prop ].call( this );
        }

        return this.parent.get__( prop, val );
    }
}


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

Спасибо, реализую!
Как упомянул trikadin, можно организовать некий приватный объект который будет иметь setters/getters для нужных значений. Я считаю это разумным подходом, к примеру:

accessors: {
    accessor1: function( val, isSet ) {
        if ( !isSet ) {
            return myValue;
        }
        myValue = val;
    }
    accessor2: function( val, isSet ) {
        if ( !isSet ) {
            return myValue;
        }
        myValue = val;
    }
}
..............
{
    $accessor1: 0,
    $accessor2: 0,
    set__: function( prop, val ) {
        accessors[ prop ] && accessors[ prop ].call( this, val, true );
    },
    get__: function( prop ) {
        return accessors[ prop ] && accessors[ prop ].call( this );
    }
}
Пишу я приложения как правило разного уровня, иногда огромные иногда мелкие. Но это ничего не меняет.

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

К примеру структура компонентов строится примерно таким образом:

1. Управляющий компонент — как правило обработка событий и общих методов.
2. Компонент канвы (форма) — расширен от управляющего, но имеет возможность зарезервировать область (не видимый прямоугольник) к примеру. На которую потом можно поместить любой компонент.
3. К примеру возьмем кнопку — расширяется от канвы, но дополняет возможность, прорисовки (заполнения области) нужным фоном/шкурой, обрабатывает события перехвата нажатия, выставление текста и т.д.
4. К примеру возьмем кнопку с картинкой — расширяется от обычной кнопки, но дополняет ее возможностью добавить рисунок (иконку) на кнопку, получается некий (BitmapButton).

И это все лишь небольшой пример того для чего нужно наследование, оно не просто упрощает жизнь программисту. Но и дает возможность создавать другие компоненты наследуя лишь те возможности которые необходимы.
Эти возможности к сожалению ограничены, и лишь подобная обертка дает возможность использовать те самые ограниченные возможности старых браузеров ИЕ, вы можете прочитать об ограничениях в одном из хабропостов
1. Зачем вам наследование? Можете привести реальный пример?

И правда зачем нам наследование, давайте все начинать с нуля… А то уж слишком мы умные и опытные стали, ведь быдь первобытным проще. САРКАЗМ

Наследование нужно что бы не плодить куча одинакового кода а использовать один и везде где понадобится. Но вы на это ответите «Ну дык можно просто сделать функцию и вызывать ее где угодно.» Да верно, можно сделать функцию, но с функцией есть ограничение того, что она будет делать либо что-то одно, либо она будет иметь сотню возможностей, о которых мы будем ей говорить при вызове, передавая параметры.

Я надеюсь ответил на ваш вопрос, о плюсах наследования можно почитать где угодно, и для этого не обязательно читать о JavaScript, ибо везде один и тот же принцип.
Данный способ был перенят из PHP, там также для классов объявляются сеттеры/геттеры общими методами. Отдельное использование приведет к тому что нужно будет выдумывать как называть методы что бы конструктор классов смог определить что для данного свойства нужен перехват. Это скорее сделано не ради удобства/неудобства а ради скорости работы конструктора классов. Ведь лишние способы приведут к долгому распарсиванию данных.

В нашем случае мы лишь объявляем свойство со знака доллар, и парсер классов просто вешает на него событие перехвата. Ведь согласитесь что написать таким образом:
{
    $acsessor1: 0,
    $acsessor2: 0,
    set__: function( prop, val ) {
    },
    get__: function( prop ) {
    }
}

на мой взгляд намного читабельно и понятно, чем писать что-то вроде этого:
{
    set__acsessor1: function( val ) {
    },
    get__acsessor1: function() {
    },
    set__acsessor2: function( val ) {
    },
    get__acsessor2: function() {
    }
}

Хотя конечно оба варианта заслуживают рассмотрения, но как я упомянул чуть выше, скорость по моему мнению, все же важнее… Так как выяснить присутствие приставок set__|get__ к свойствам займет чуток больше времени выполнения, нежели простая проверка первой буквы у свойства.

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

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity