美文网首页
(随笔)Javascript实现singleton(单例模式)和

(随笔)Javascript实现singleton(单例模式)和

作者: 神秘老王 | 来源:发表于2018-08-29 14:24 被阅读0次

总体思路就是用闭包实现的singleton(单例模式)以及DI(依赖注入),所有的service都是驻留在内存中,Provider下声场的s1,s2,s3是唯一的且全局可访问的(下面例子中其实就是injector)controller在实例化的时候可以直接根据参数获取到相应的service实例从而调用,这样就实现了在controller中的DI,注入自定义的provider或者service(服务),而无需自己手动import进来,当然,真正angularJS中要比这个要复杂很多,因为还包含了scope(作用域)的管理,以及循环依赖一些的异常处理,包括还有一个全局的$injector provider可以显式的DI 类似 ctr1.$injector = ['service1', 'service2',....];

服务

var Provider = (function(){
    var injector = {};
    
    return {
        
        service: function(serviceName, fn){
            if(!injector[serviceName]){
                injector[serviceName] = fn();
            }else{
               console.log('already has a instance');
            }
        },
        inject: function(serviceName){
            if(!injector[serviceName]){
                console.log('no instance for'+ serviceName);
                
            }
                return injector[serviceName];
        }
    }
})();

控制器

function Controller(ctrlName, fn){
    var injector = Provider;
    return  function(){
        //是否有显式的指定相应的DI 没有则尝试取形参
        var serviceList = fn.$injector ? fn.$injector : getArgumentsList(fn);
        var serviceImpList = [];

        serviceList.forEach(function(serviceName){
            serviceImpList.push(injector.inject(serviceName));
        });
        fn.apply(null, serviceImpList)
    }

    
};




function getArgumentsList(func){
    var funcString = func.toString();
    var regExp =/function\s*\w*\(([\s\S]*?)\)/;
    if(regExp.test(funcString)){
        var argList = RegExp.$1.split(',');
        return argList.map(function(arg){
                return arg.replace(/\s/g,'');
            });
    }else{
        return []
    }
}

服务初始化

Provider.service('s1', function(){
    return {name: 's1'};
})


Provider.service('s2', function(){
    return {name: 's2'};
})


Provider.service('s3', function(){
    return {
        name: 's3',
        sayHello: function(){
            console.log('hello i m s3');
        }
    };
})
Provider.service('s4', function(){
    return {
        name: 's4',
        getName: function(t){
            console.log('hello i m '+ t);
        }
    };
})
var fn1 = function(s1,s2,s3){
    // console.log(this);
    console.log(s1);
    console.log(s2.name);
    console.log('change s2 name to patrick');
    s2.name = 'patrick';
    console.log(s3.sayHello())
};
var fn2 = function(s2, s4){
    console.log(s2.name);
    console.log(s4.getName('wxy'))
}
var fn3 = function(s2, s4){
    console.log(s2.name);
    console.log(s4.getName('wxy2'))
}
//DI
fn3.$injector = ['s2', 's4'];
var ctr3 = new Controller('c3Name', fn3);
var ctr1 = new Controller('c1Name', fn1);
var ctr2 = new Controller('c2Name', fn2);

ctr1();
ctr2();
ctr3();

相关文章

网友评论

      本文标题:(随笔)Javascript实现singleton(单例模式)和

      本文链接:https://www.haomeiwen.com/subject/tfahwftx.html