Pull to refresh

Comments 8

>Но всё это ужасно не красиво и не правильно

Скорее наоборот. Чем вам 'this'-то не угодил?
Дело в том, что this относится к объекту, методом которого является исполняемая функция, и внутри функции значение this может меняться. Вот простой пример:

function testThis(){
alert(this); // здесь this == window
$('img').each(function(){
alert(this); // здесь this == image
})
}
testThis()
Ваш персиковый пример берёт 'this' и от него же отталкивается — «persik = this, actions = persik.actions» и так далее, то есть переменные не нужны, уже есть 'this'. Пользователь, создавая свой метод, конечно может столкнуться с необходимостью сохранить 'this' в переменную (замыкание нарисует или ещё чего), но необязательно же так и будет, а если будет, так он сам определит решение. Ваш вариант принуждает его заранее (раз), гонит через ресурсоёмкий eval все методы подряд (два), перекрывает ряд имён — 'a', 'func', 'funcName' и так далее (три), полагается на 'toString', который возвращает «implementation-dependent representation of the function», то есть может вернуть всё что угодно, вплоть до нерабочего кода (четыре)…
Вся вышеперечисленная критика, безусловно, справедлива, и ради «persik = this, actions = persik.actions» я бы не стал ввязываться в авантюру с инъекциями, но как же быть с next, который ОБЯЗАТЕЛЬНО должен быть вызван в каждом методе actions? В первоначальном варианте я везде писал что-то вроде if (persik.dom.menu.level1._onStartClose.next) persik.dom.menu.level1._onStartClose.next();, но лично меня такие конструкции в каждом методе угнетают. Конечно можно было бы перед каждым вызовом методов объекта persik определять window.next(), но в данном случае это неприемлемо, т.к. методы actions определяют анимацию приложения, и если во время выполнения одного метода будет вызван другой, это спровоцирует переопределение window.next() и неизбежную ошибку после вызова next() в первом методе. Так что остановился на инъекциях.
Может в консерватории надо что-то подправить? То есть проблему надо решать на более высоком уровне, а парсить функции, заменять там строки, да ещё и гнать eval — это, уж простите, ламерство какое-то.
Если берёте на себя ответственность уличать меня в ламерстве, тогда уж предложите свой, «высокоуровневый» вариант решения задачи
Я всегда готов «ответить за базар» :)
Ну самый простой способ это передавать все эти три переменный в this и доступаться к ним по this.persik, this.actions и this.next. Тогда _rewriteFunc может выглядеть как

_rewriteFunc: function (func, next) {
    var that = {persik: this, actions: this.actions, next: next || function() {}};
    return function() { func.apply(that, arguments); };
}
Несколько раз перечитал пост, как-то запутанно, или это я к вечеру плохо соображаю. Но если я все правильно понял, то почему бы просто не переопределить прототит Function вписав в него создание нужных вам переменных?
Sign up to leave a comment.

Articles