1

我有这两种方法:

Cluster.prototype.initiate_xhr_request = function(url, callback) {
    var self = this,
        request = (Modernizr.test_xmlhttprequest) ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
    request.onreadystatechange = function() {
        if(request.readyState === 4) {
            switch(request.status) {
                case 200:
                    callback.apply(request,[ request.statusText ]);
                    break;
                case 400:
                    callback.apply(request,[ request.statusText ]);
                    break;
                default:
                    break;
            };
        } else 
            console.log('An error occured during the XHR request');
        }
    };
    request.open("HEAD", url, false);
    request.send();
};

Cluster.prototype.operations = {
    '&&': function(array){ 
        return array.reduce(function(previousValue, currentValue, index, array){
             return previousValue && currentValue;
         })
     },
    '||' : function(array){
        return array.reduce(function(previousValue, currentValue, index, array){
            return this.initiate_xhr_request(previousValue) || currentValue;
        })}
};

编辑:调用方法如下:

Cluster.prototype.calculate = function(operation, array){
    return this.operations[operation](array);
};

/* call the calculate function */

this.calculate('&&', some_array);

显然,这条线this.initiate_xhr_request(previousValue)行不通。我一直试图找到一个很好的解决方案来做我想做的事情,但我找不到一个(:有没有办法做到这一点并保持我的结构不变?

4

1 回答 1

1

您可以使用.call.apply手动设置this您正在调用的方法的值。

这里我将this值设置this.operations[operation]为当前词法环境中的值。(使用.apply而不是.call会做同样的事情,但会将你array的成员作为单独的参数传递,你似乎不想要。)

Cluster.prototype.calculate = function(operation, array){
    return this.operations[operation].call(this, array);
};

现在在这些方法中,this值将是您所期望的,除了您需要确保该this值保留在.reduce()该方法的 then 回调中"||"

做到这一点的经典方法是保留对外部词法环境的变量引用,即回调中该变量的引用:

Cluster.prototype.operations = {
    '&&' : ...,
    '||' : function(array){
        var self = this;
        return array.reduce(function(previousValue, currentValue, index, array){
            return self.initiate_xhr_request(previousValue) || currentValue;
        })}
};

但更现代的方法是使用手动绑定值Function.prototype.bind创建一个新函数:this

Cluster.prototype.operations = {
    '&&' : ...,
    '||' : function(array){
        return array.reduce(function(previousValue, currentValue, index, array){
            return this.initiate_xhr_request(previousValue) || currentValue;
        }.bind(this))}
};
于 2012-10-21T18:20:20.653 回答