Skip to content

3、代理模式

js
// 1
var myImage = (function(){
    var imgNode = document.createElement( 'img' );
    document.body.appendChild( imgNode );
    return {
        setSrc: function( src ){
            imgNode.src = src;
        }
    }
})();
var proxyImage = (function(){
    var img = new Image;
    img.onload = function(){
        // onload成功之后,替换为rc
        myImage.setSrc( this.src );
    }
    return {
        setSrc: function( src ){
            // 首先设置一个loading 图片
            myImage.setSrc( 'file:// /C:/Users/svenzeng/Desktop/loading.gif' );
            // new Image 设置src
            img.src = src;
        }
    }
})();
proxyImage.setSrc( 'http://imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );
// 2
// 只返回方法
// 如果代理对象和本体对象都为一个函数(函数也是对象),函数必然都能被执行,则可以认为它们也具有一致的“接口”
var myImage = (function(){
    var imgNode = document.createElement( 'img' );
    document.body.appendChild( imgNode );
    return function( src ){
        imgNode.src = src;
    }
})();
var proxyImage = (function(){
    var img = new Image;
    img.onload = function(){
        myImage( this.src );
    }
    return function( src ){
        myImage( 'file:// /C:/Users/svenzeng/Desktop/loading.gif' );
        img.src = src;
    }
})();
proxyImage( 'http://imgcache.qq.com/music// N/k/000GGDys0yA0Nk.jpg' );
// 3
// 节流也是一种代理
// 虚拟代理合并http请求
var synchronousFile = function( id ){
    // console.log( ’开始同步文件,id为: ' + id );
};
var proxySynchronousFile = (function(){
    var cache = [],    // 保存一段时间内需要同步的ID
        timer;    // 定时器
    return function( id ){
        cache.push( id );
        if ( timer ){    // 保证不会覆盖已经启动的定时器
            return;
        }
        timer = setTimeout(function(){
            synchronousFile( cache.join( ', ' ) );    // 2秒后向本体发送需要同步的ID集合
            clearTimeout( timer );    // 清空定时器
            timer = null;
            cache.length = 0; // 清空ID集合
        }, 2000 );
    }
})();
var checkbox = document.getElementsByTagName( 'input' );
for ( var i = 0, c; c = checkbox[ i++ ]; ){
    c.onclick = function(){
        if ( this.checked === true ){
            proxySynchronousFile( this.id );
        }
    }
};
// 4 脚本记载
var miniConsole = (function(){
    var cache = [];
    var handler = function( ev ){
        if ( ev.keyCode === 113 ){
            var script = document.createElement( 'script' );
            script.onload = function(){
                // keydown以后 负责真正打印
                for ( var i = 0, fn; fn = cache[ i++ ]; ){
                    fn();
                }
            };
            script.src = 'miniConsole.js';
            document.getElementsByTagName( 'head' )[0].appendChild( script );
            document.body.removeEventListener( 'keydown', handler ); // 只加载一次miniConsole.js
        }
    };
    document.body.addEventListener( 'keydown', handler, false );
    return {
        log: function(){
            var args = arguments;
            // 负责存储
                cache.push(function(){
                    // 这里是miniConsole.js的miniConsole
                    return miniConsole.log.apply( miniConsole, args );
                });
        }
    }
})();
miniConsole.log( 11 );      // 开始打印log
// miniConsole.js 文件的代码
miniConsole = {
    log: function(){
        // 真正代码略
        console.log( Array.prototype.join.call( arguments ) );
    }
};
// 5 代理缓存
var mult = function(){
    var a = 1;
    for ( var i = 0, l = arguments.length; i < l; i++ ){
        a = a * arguments[i];
    }
    return a;
};
mult( 2, 3 );    // 输出:6
mult( 2, 3, 4 );    // 输出:24
var proxyMult = (function(){
    var cache = {};
    return function(){
        var args = Array.prototype.join.call( arguments, ', ' );
        if ( args in cache ){
            // 有缓存直接返回
            return cache[ args ];
        }
        return cache[ args ] = mult.apply( this, arguments );// 计算结果进行缓存
    }
})();
proxyMult( 1, 2, 3, 4 );    // 输出:24
proxyMult( 1, 2, 3, 4 );    // 输出:24
// 动态创建代理
/**************** 计算乘积 *****************/
var mult = function(){
    var a = 1;
    for ( var i = 0, l = arguments.length; i < l; i++ ){
        a = a * arguments[i];
    }
    return a;
};
/**************** 计算加和 *****************/
var plus = function(){
    var a = 0;
    for ( var i = 0, l = arguments.length; i < l; i++ ){
        a = a + arguments[i];
    }
    return a;
};
/**************** 创建缓存代理的工厂 *****************/
var createProxyFactory = function( fn ){
    var cache = {};
    return function(){
        var args = Array.prototype.join.call( arguments, ', ' );
        if ( args in cache ){
            return cache[ args ];
        }
        return  cache[ args ] = fn.apply( this, arguments ); // fn
    }
};
var proxyMult = createProxyFactory( mult ),
proxyPlus = createProxyFactory( plus );
alert ( proxyMult( 1, 2, 3, 4 ) );    // 输出:24
alert ( proxyMult( 1, 2, 3, 4 ) );    // 输出:24
alert ( proxyPlus( 1, 2, 3, 4 ) );    // 输出:10
alert ( proxyPlus( 1, 2, 3, 4 ) );    // 输出:10