有没有替代技术来关闭JavaScript?

时间:2012-12-18 13:58:25

标签: javascript closures

在下面的代码中,我使用闭包来“保存”“this”引用并将其传递给回调。但我想知道,有没有其他技术来完成同样的事情?

function App()
{   
    this.number = 75;
}

App.prototype.xmlHandler = function(self)
{
    if (this.number == 99) //true at run-time
        console.log("this.number == 99 is true");
    else
        console.log("this.number == 99 is false");

    if (self.number == app.number) //true at run-time
        console.log("self.number == app.number is true");
    else
        console.log("self.number == app.number is false");
};

App.prototype.loadXML = function(url, handler)
{
    var self = this;
    var req = new XMLHttpRequest();
    req.number = 99;
    req.addEventListener("load", function(){handler.call(req, self);}, false);
    req.open('GET', url, true);
    req.send();
};

App.prototype.init = function()
{
    this.loadXML('resources.xml', this.xmlHandler);
};

var app = new App();
app.init();

在xmlHandler方法下,基本上有两个不同的“this”(一个[this]用于req对象,另一个[self]用于app对象)。那么,是否有其他技术可以在一个屋檐下获得两个不同的“这个”值?

4 个答案:

答案 0 :(得分:1)

有一些实用程序函数可以创建一个闭包,但没有详细程度。

在这种特殊情况下,您可以使用ES5 Function.bind方法(旧版浏览器可以使用填充程序):

App.prototype.loadXML = function(url, handler) {
    var req = new XMLHttpRequest();
    req.number = 99;
    req.addEventListener("load", handler.bind(this, req), false);
    req.open('GET', url, true);
    req.send();
};

结果将是handler(等于this.xmlHandler)将被调用this仍然等于其原始值(即App对象)和以req作为第一个参数。

严格地说,这与您当前对xmlHandler的定义相反,但让this引用App对象代替它更合乎逻辑的恕我直言作为参数传递。然后写下这个函数:

App.prototype.xmlHandler = function(req, evt) {
    if (req.number == ...) {
        ...
    }
    ...
}

注意evt参数如何也可用 - .bind中传递的参数预先到浏览器提供的任何参数。

答案 1 :(得分:0)

一般来说,闭包没有其他选择。

对于this绑定,如果只需要其中一个,则可以使用.bind() Function method(ES5.1本机,可轻松缩放)。对于“两个不同的'这个'值”,您可能需要编写一个类似的函数,将第二个上下文作为参数传递,但是闭包比imho更简单。

答案 2 :(得分:0)

实际上,使用闭包的唯一方法是使用闭包。

那就是说,看看你的代码,我认为.loadXML()根本不应该关心上下文:

App.prototype.loadXML = function(url, handler)
{
    var req = new XMLHttpRequest();
    req.number = 99;
    req.addEventListener("load", handler, false);
    req.open('GET', url, true);
    req.send();
};

这会清理函数,因此您可以在.init()内表达您真正想要做的事情:

App.prototype.init = function()
{
    var self = this;

    this.loadXML('resources.xml', function(evt) {
        // this refers to the XMLHttpRequest
        // self refers to the current App instance
        self.xmlHandler(this);
    });
};

答案 3 :(得分:0)

这可能不是你想要的。无论如何,这是分享'这个'。 对象“内在”并没有保留其对象性,因为它已成为“外部”的一种方法,但它正在共享。

如果您正在寻找比我在此处所写的更具体的内容,请告诉我。

<html>
<head>
</head>
<body>
<p id="result1"></p>
<p id="result2"></p>
</body>
<script>

var outer = function(val, obj){

    this['inner'] = obj['inner'];
            this.val = val;
    this.inner('result1')
    this.val2 = 'not 2';
    this.inner('result2');
};
var inner = function(id){
    this.val2 = this.val2 || 2;
    document.getElementById(id).innerHTML = 'this.val='+this.val+'this.val2='+this.val2;

};

new outer('thing', {'inner': inner});
</script>
</html>