All streams
Search
Write a publication
Pull to refresh
213
0
Rostyslav @Kottenator

Front-End Engineer

Send message
Ну всё, теперь можно искать «скрытые послания» во всех картинках в Инете :) Кстати, отличная идея — хранит ьсвои, скажем, самые секретные данные — в своих фотках на каком-то фотосайте. И запомнится легко — ассоциации с фоткой :)
Зато в SVN есть атомарная история каждой мелочи, чем я активно пользуюсь. В Git её нет.
Спасибо, полезная статья. С неё можно начать использовать Git и потихоньку уходить от SVN :-)
Хотя в своём интервью Линус Торвальдс говорил, что SVN продолжает отлично работать в большинстве проектов, но Git хорош в больших и сильно распределённых проектах.

Так что надо пробовать, и самому делать выводы.
Ясно. Ну значит есть повод ещё разок обновить код ;-)
Угу. Но я побоялся использовать словосочетание «аспектно-ориентированный подход» в своей статье, т.к. ничего об этом в ней не писал.
Критиковал я Ajaxpect версии 0.9.0, скачал которую в 11:30 UTC time с code.google.com/p/ajaxpect/, чтобы потом на меня не наехали, что ничего такого в коде нет :)
Раз уж вы дали здесь рекламу своего фреймворка Ajaxpect, напишу на него свою небольшую критику :-)
Я почитал ваш код и выделю следующее:
Плюсы:
1) Отвязанность от прототипов стандартных объектов, вроде Object и Function (всё делается через объект Ajaxpect)
2)Продвинутый и довольно удобный поиск методов в объекте:
* можно задать имя метода
* можно задать функцию-фильтр, которая возвращает true, если переданное в неё имя метода соответствует неким условиям
* можно задать RegExp, который также фильтрует имена методов объекта
Теперь минусы:
1) Самое плохое — нет возможности снять навешенный декоратор. Сейчас у вас это можно сделать только внутри самого декоратора, но довольно хитро. А если навесить декоратор дважды, то такая возможность и вовсе исчезнет.
2) Само разделение методов addBefore, addAfter и addAroundнедоработано. К примеру:
* addAfter легко выкидывается и реализуется через addAround, т.к. вы передаёте в декоратор и оригинальную ф-цию, и её аргументы
* addBefore — вы сначала выполняете функцию-декоратор, которая по сути возвращает изменённые arguments в оригинальную ф-цию, и тут же вызываете оригинальную ф-цию. Декоратор «before» должен иметь возможность остановить выполнение оригинальной ф-ции.

Это основное, что я заметил.

Теперь давайте сравним с моим творением — у меня всё с точностью до наоборот:
Минусы:
1) Я «засорил» стандартный объект Function.
2) У меня самый простой способ поиска метода: по имени.
3) Да, и у меня нет в явном виде вашего addAround. Но он легко реализуем у меня через Function.decorate(...).
Но плюсы:
1) Есть removeBefore(...) и removeAfter(...).
2) «Хорошая» организация стэка listener'ов
3) «Хорошая» реализация addBefore: если хоть один из addBefore-listener'ов возвращает false, оригинальная ф-ция не выполнится.

По мощности моя реализация равна вашей. но я бы вам советовал разложить всё по полочкам и учесть мои замечания. К тому же, я написал эту статью в ознакомительных целях. По сути мой код можно оформить в отдельный framework, но я пока не хочу этого делать :-)
Спасибо, что заметили. Сначала я использовал [].slice.apply(arguments), но потом подумал, что это излишне, и заменил на просто arguments. Но получается, что заменил не везде :-) Я это исправил.
Ну хорошо, в будущем я постараюсь не использовать слово "класс" в контексте Javascript :)

Я навёл справки в документации ECMA-262: там используются следующие термины для функций:
1) Метод — функция, хранимая в свойстве объекта.
2) Конструктор — объект типа Function, который создаёт и инициализирует объекты.
3) А также функцию можно называть объектом типа Function.

Заметьте: просто конструктор, но не конструктор класса, и это принципиально.

Почитать ещё можно тут: http://javascript.ru/ecma/part4
Ну, ключевое слово debugger может ничего и не даст, если отсутствует хоть какой-то debugger. Однако в любом браузере можно написать нечто следующее:
javascript:f=function(x){alert(x)};f=f.decorate(function(x){alert('decorator: '+x); arguments.callee.old.apply(this, arguments)});f(5);

* This source code was highlighted with Source Code Highlighter.

прямо в адресной строке любого браузера. Так и дебажить, простым alert() :-)
Спасибо всем за карму. Перенёс в Javascript.
>> 1) Изменение базовых объектов (Function, Array, Object, etc.) — порочная практика.
Совершенно согласен. Но всё-таки Function.method, Function.decorate и Function.restore — красиво. От остального можно избавиться.

>> 2) Путица вида «класс, класс Function, ой, в Javascript нет классов» в пункте «Нырнем на пару метров вглубь». Лучше бы определиться.
Извиняюсь, мне просто было удобно использовать слово «класс». Википедия пишет так:
Javascript uses prototypes instead of classes for defining object properties, including methods, and inheritance. It is possible to simulate many class-based features with prototypes in Javascript.
А значит классов здесь никаких нет :)
Можно. Но что, если у вас нет возможности их ставить? Например, у вас — Internet Explorer 6, без script debugger-плагина. Или Opera 8.5
А, вот оно что :)
В зачатках мой код был очень похож на ваш. Но чем дальше в лес, тем толще партизаны.

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

Глянул в тот же Ext, на объект Observable, и понял, что необходимо иметь addListener и removeListener.

Ну и идея пошла дальше Ж)
Ели честно, то ноги у идеи растут именно оттуда, откуда вы сказали :)
Мне надо было сделать debug вызова некоторых ф-ций в IE. Можно, конечно, просто «остановить» поток коммандой debugger. Но что если в браузере нет отладчика, или нет доступа к исходному коду?
Вообщем, если эта статья народу понравится, я мог бы подумать над применениями моего кода.
Собственно, можете предлагать, а я смогу это учесть :)
А, вы про сам Ext.override?

Так ведь приведённый мой Function.method(...) — в точности то же самое, только аргументы передаются не Object'ом, как в Ext.override, а именнем+значением.
Да, и моя реализация before('smth', ...) — может отменить выполнение основной ф-ции )
Согласен, в чём-то у меня сложней, чем у ExtJS :)

Но во-первых, я излагал материал в развёрнутом виде, для читабельности.

А во-вторых, мой механизм является более универсальным:
вот смотрите, код Ext'а использует _this, который просто вызывается внутри декоратора. В то время, как мой декоратор имеет внутри себя ссылку на оригинальную ф-цию, что важно. Мой декоратор по сути полностью «оборачивает» исходную ф-цию, и манипулирует ей внутри себя как хочет. В то время, как Ext-овский вариант просто добавляет вызовы «до» и «после».

Ну и в моём варианте я могу не просто «навешивать» вызовы «до» и «после», но и убирать их. И это не вызовет code mess.
Люди, я тут — новенький, поэтому могу немного «косячить». Извиняюсь за «много букв», но статья по-моему завершена по своей структуре.

И ещё: я не знаю как, но очень хотелось бы перенести её в блог «Javascript»
12 ...
12

Information

Rating
Does not participate
Date of birth
Registered
Activity