【问题标题】:Javascript object binding problem inside of function prototype definitions函数原型定义中的Javascript对象绑定问题
【发布时间】:2010-06-10 22:16:38
【问题描述】:

我正在尝试找出合适的位置来绑定稍后调用的函数原型。示例的完整代码可以在这里找到:

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);

如果您尝试在 Firebug 中运行 myo.test(),您将得到“this.doAnotherAction is not a function”响应。如果您希望查看它们,可以在 test.js 链接中找到 2 个支持函数 init() 和 parseResponse(),但不应与此问题太相关。我已经确认 this.doAnotherAction() 认为“this”是 instanceof 测试中所预期的 XMLHttpResponse 对象。

谁能提供一些关于绑定方向的见解?我尝试过的一切似乎都不起作用!

我确实使用了 Mootools,尽管此示例中没有该库。

提前致谢,

阿里昂

【问题讨论】:

    标签: javascript function binding prototype object


    【解决方案1】:

    xhr.onreadystatechange 内部的this 不引用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() 在您的测试页面上进行测试:)

    【讨论】:

    • 好家伙,当我这样做时它确实有效。不过,为了避免正确使用函数绑定,这似乎有点不合时宜,不是吗?我很感谢您提供了一个可行的答案,但是在这种情况下,对绑定的性质有什么想法吗?万分感谢!!! :)
    • 函数绑定的正确使用是什么意思?分配给onreadystatechange(即this)的匿名函数内部的函数上下文是xmlHttpRequest 对象。如果没有在 Obj 实例的上下文中应用该函数(如 Anurag 的回答),我认为无论如何都没有。因此,您需要在变量中捕获外部上下文,并在内部函数中使用该变量。
    【解决方案2】:

    ECMAScript 第 5 版。从 Prototype 框架中借用了函数的 bind 方法。你可以将它包含在你的代码中,如果它不存在,它将定义一个绑定方法。

    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);
    

    【讨论】:

    • ahhh 好的,所以我之前的问题是我试图将 bind(this) 添加到 test() 或 doAnotherAction() 方法中,而我应该将“this”绑定到 onreadystatechange 回调.
    猜你喜欢
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多