memoize使用实例之创建XHR

首先看看创建XHR最简单的方法:

function createXHR() { // Factory method.  
    var methods = [  
        function() { return new XMLHttpRequest(); },  
        function() { return new ActiveXObject('Msxml2.XMLHTTP'); },  
        function() { return new ActiveXObject('Microsoft.XMLHTTP'); }  
    ];  
    var xhr;  
    for (var i = 0, len = methods.length; i < len; i++) {  
        try {  
            xhr = methods[i]();  
        } catch(e) {  
            continue;  
        }  
        // If we reach this point, method[i] worked.  
        return xhr;  
    }  
    throw new Error('Could not create an XHR object.');  
}  

我们调用createXHR函数来发起一个ajax请求,该函数会在内部遍历查找当前浏览器可用的xhr类型,然后返回。但显然每次都要循环一遍是没有必要的,能否让函数记住上一次返回的结果呢。

 在Pro Javascript design patterns一书里,可以看到这样的解决方法:

function createXHR2() {  
    var methods = [  
        function() { return new XMLHttpRequest(); },  
        function() { return new ActiveXObject('Msxml2.XMLHTTP'); },  
        function() { return new ActiveXObject('Microsoft.XMLHTTP'); }  
    ];  
    var xhr  
    for (var i = 0, len = methods.length; i < len; i++) {  
        try {  
            xhr = methods[i]();  
        } catch(e) {  
            continue;  
        }  
        createXHR2 = function() {// cache it  
            return xhr;  
        }  
        return methods[i];  
    }  
    throw new Error('Could not create an XHR object.');  
}  

可以看到14行的作用是,在函数第一次执行之后,把函数自身给替换了,当函数第二次执行时,直接就是return xhr;,这种做法使得函数具有了记忆功能。

 很巧妙的做法,但这样做的代价是,让一个函数多实现了一个它本不该有的功能,即cache功能,对于函数功能单一性的原则说,这种做法算不上完美。

 可能经常会碰到这种需要记忆的函数,这种机制需要被抽象出来:

(以下代码来源于 Memoization in JavaScript,略有改动)

function asArray(quasiArray, start) {  
    var r = [];  
    for (var i = (start || 0); i < quasiArray.length; i++)  
        r.push(quasiArray[i]);  
    return r;  
}  
  
Function.prototype.memoize = function(scope) {  
    var cache  = {};  
    var self = this;  
    scope = scope !== undefined ? scope : null;  
  
    var memoizedFn = function() {  
        var key = asArray(arguments).toString();  
  
        if (!(key in cache)) {  
            cache[key] = self.apply(scope, arguments);  
        }  
  
        return cache[key];  
    };  
  
    memoizedFn.unmemoize = function() {  
        return self;  
    };  
  
    return memoizedFn;  
};  

注:arguments是类似数组的东东,有部分数组特性,比如arguments[0],但没有toString()之类数组内置方法,所以需要用asArray将其转换为数组。

var memoizedCreateXHR = createXHR.memoize();  
  
console.info(memoizedCreateXHR());  

关于memoization的更多应用,可以参考

speed-up-your-javascript-part-2/

One-Line JavaScript Memoization

Timed Memoization 

 

转载于:https://www.cnblogs.com/aj3423/archive/2011/02/28/3150514.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值