Помогите понять, правильно ли написал я JS код

Духовность™

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

В общем, как мы знаем, для асинхронных запросов нужно определить onreadystatechange свойство XmlHttpRequest. Что бы это делал клиент, я предусмотрел два способа определения onreadystatechange, один из которых выглядит так:

PHP:
...
// анонимная функция будет вызываться при событии onreadystatechange 
ajax.setObserverState(function(){ alert('Привет, я результат запроса: ' + ajax.getText()) });
ajax.get(...)
реализовано это так:
PHP:
this.setObserverState = function(observer_function)
{
    this.observerState = function()
    {
        if (req.readyState==4) {
            if (req.status == 200) {
            	observer_function();
            }
        }
    }
}

// ... 

req.onreadystatechange = this.observerState;
Что тут происходит? Инстансу главного объекта ajax присваивается функция, которая должна быть исполнена при onreadystatechange. Но в теле функции я пишу фактически ссылку на сам инстанс. Это вообще нормально? Я так понимаю, я передаю таким способом ссылку на самого себя?
 

craz

Нестандартное звание
А вот поэтому то и нужно учить JS:

В JavaScript this всегда относится к «владельцу» выполняемой функции, или, если быть точнее, к объекту, методом которого является функция.

http://javascript.ru/this
http://www.quirksmode.org/js/this.html
ну триуму то уже давно пора его выучить...
 

Духовность™

Продвинутый новичок
А вот поэтому то и нужно учить JS:

В JavaScript this всегда относится к «владельцу» выполняемой функции, или, если быть точнее, к объекту, методом которого является функция.

http://javascript.ru/this
http://www.quirksmode.org/js/this.html
Гы, кто-то сказал/, что я\не хочу учить JS?

И причем тут this?
 

Духовность™

Продвинутый новичок
Замыкания вещь полезная, да. Но вот что меня смутило - замыкание нельзя организовать извне, .передав внутреннюю функцию. Т.е. вот корректный пример:

PHP:
foo = function()
{
    var val = 111;

    var zamikanie = function()
    {
        alert(val);
    }
    window.onload = zamikanie;
    
}
foo();
А вот так нельзя :(

PHP:
foo = function(zam)
{
    var val = 111;

    var zamikanie = zam;
    window.onload = zamikanie;
    
}
foo( function(){alert(val);} );
 

Adelf

Administrator
Команда форума
в js с функциями можно делать почти все, кроме очевидно глупых вещей. То как ты хочешь - вообще бред и ведет к запутыванию.
с jQuery или ExtJs можно сделать то, что ты хочешь в неправильном варианте. Там можно в event передавать контекст(т.е. содержимое this). Товарищ Yehuda Katz говорил на DevConf::RichClient что именно так надо работать с эвентами.
 

A1x

Новичок
foo( function(){alert(val);} ); - берет глобальную переменную val, которая никак не связана с внутренней переменной val функции foo
 

Crys

Двинутый новичок
А по-моему, triumvirat хочет открыть для себя биндинг... Типа такого

Код:
<script type="text/javascript">
foo = function(zam)
{
    var val = 111;

    window.onload = function(val){
        this(val);
    }.apply(zam,[val]);

}
var val = 0;
foo( function(val){alert(val);} );
</script>
Пример не кроссбраузерный (но работает в FF).
 

Духовность™

Продвинутый новичок
параметром передать, вообще-то.
сенкс!!! то что надо. элементарно в общем то все решилось)

Теперь я могу назначить обработчик события и работать в нем либо напрямую с объектом xmlHttpRequest, либо через специфические методы самого класса. УУиии!!

PHP:
	ajax.setObserverState(
            function(a, r){
                alert(
                    a.getText() + ' ' + // a - замыкание на объект Ajax
                    r.responseText); // r - ссылка на объект xmlHttpRequest
            }
        );
а реализовал назначение обработчика так, через замыкание и через this:

PHP:
this.setObserverState = function(observer_function)
{
    var ajax_object = this;

    this.observerState = function()
    {
        if (this.readyState == 4) {
            if (this.status == 200) {
                    observer_function(ajax_object, this);
            }
        }
    }
}
 
Сверху