Проблема привязки объекта Javascript внутри определения прототипа функции - PullRequest
1 голос
/ 11 июня 2010

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

http://www.iprosites.com/jso/

Мой пример JavaScript очень прост:

function Obj(width, height){
    this.width = width;
    this.height = height;
}

Obj.prototype.test = function(){
    var xhr=init();
    xhr.open('GET', '?ajax=test', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    xhr.onreadystatechange = function() {
        if (xhr.responseText == '403') {
            window.location.reload(false);
        }
        if (xhr.readyState == 4 && xhr.status == 200) {
            this.response = parseResponse(xhr.responseText);
            document.getElementById('resp').innerHTML = this.response.return_value;
            this.doAnotherAction();
        }
    };
    xhr.send();
}

Obj.prototype.doAnotherAction = function(){
    alert('Another Action Done');
}


var myo = new Obj(4, 6);

Если вы попытаетесь запустить myo.test() в Firebug вы получите ответ «this.doAnotherAction is not function».2 функции поддержки init () и parseResponse () можно найти в ссылке test.js, если вы хотите их просмотреть, но они не должны быть слишком актуальны для этой проблемы.Я подтвердил, что this.doAnotherAction () считает, что «this» - это объект XMLHttpResponse, как и ожидалось от экземпляра теста.

Может ли кто-нибудь помочь с определением направления связывания?Все, что я пробовал, похоже, не работает!

Я использую Mootools, хотя библиотека в этом примере отсутствует.

Заранее спасибо,

Арион

Ответы [ 2 ]

1 голос
/ 11 июня 2010

ECMAScript 5-е изд. заимствовал метод bind для функций из среды Prototype. Вы можете включить его в свой код, который определит метод связывания, если он еще не существует.

if (!Function.prototype.bind)
{
    Function.prototype.bind = function() {
        var fn = this, 
            args = Array.prototype.slice.call(arguments), 
            object = args.shift();

        return function() {
            return fn.apply(object,
                args.concat(Array.prototype.slice.call(arguments)));
        };
    };
}

После определения вы можете связать анонимную функцию внутри обратного вызова onreadystatechange с объектом Obj.

xhr.onreadystatechange = function() {
    ...
}.bind(this);
1 голос
/ 11 июня 2010

this внутри xhr.onreadystatechange не относится к экземпляру Obj.вам нужно захватить this вне функции в локальной переменной, а затем использовать это внутри xhr.onreadystatechange.то есть

Obj.prototype.test = function(){
    var obj = this,
        xhr=init();
    xhr.open('GET', '?ajax=test', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    xhr.onreadystatechange = function() {
        if (xhr.responseText == '403') {
            window.location.reload(false);
        }
        if (xhr.readyState == 4 && xhr.status == 200) {
            this.response = parseResponse(xhr.responseText);
            document.getElementById('resp').innerHTML = this.response.return_value;
            obj.doAnotherAction();
        }
    };
    xhr.send();
}

Проверьте это на своей тестовой странице, вставив вышеуказанное в консоль, а затем запустите myo.test():)

...