为你的javascript提供脚本配置

一件我很固执和坚持的事就是,写代码时分离出来一个可定制的配置对象。我现在写的脚本一般都长这样:

var module =function(){
 config ={
    CSS:{
     classes:{
       hover:'hover',
       active:'current',
       jsEnabled:'js'},
     ids:{
       container:'maincontainer'}
    },
    timeout:2000,
    userID:'chrisheilmann'
 };

  function init(){
  };

  // ... more methods and other code ...

  return{
    init:init
  };}();
module.init();

这样的好处十分明显:
当实施者修改时,不必满屏幕找代码,这里明显的表明:改这里吧。这允许更多的开发者用你的代码。你显示一个地方可以重写的地方给实施者。
比如你可以通过定义html文档的ID和CSS类名来应用到元素。
配置对象的属性都是字符串可以更好的定位和加速脚本。
有时你不是初始化,而想更改配置项,最简单的方式就是让配置对象暴露出来:

var module =function(){// configuration, change things herevar config ={
    CSS:{
     classes:{
       hover:'hover',
       active:'current',
       jsEnabled:'js'},
     ids:{
       container:'maincontainer'}},
    timeout:2000,
    userID:'chrisheilmann'};

  // start of main code 
  function init(){
  };
  // ... more methods and other code ...

  // make init and config a public method
  return{
    init:init,
    config:config
  };}();

在这种情况下你可以这样在用init之前重写你的配置项属性:

module.config.CSS.ids.container='header';
module.config.userID='alanwhite';  
module.init();

一种更简便的方式是将一个对象作为一个参数在init()中,你可以通过检查这个对象遍历递归它的属性匹配配置对象

var module =function(){// configuration, change things herevar config ={
    CSS:{
     classes:{
       hover:'hover',
       active:'current',
       jsEnabled:'js'},
     ids:{
       container:'maincontainer'}},
    timeout:2000,
    userID:'chrisheilmann'};


  // start of main code 
  function init(){
  // check if the first argument is an objectvar a =arguments;
      if(isObj(a[0])){
          var cfg = a[0];
          for(var i in cfg){
              setConfig(config,i,cfg[i]);
          }
      }
   };

  function setConfig(o,p,v){
  // loop through all the properties of he object
      for(var i in o){
        if(isObj(o[i])){ 
            setConfig(o[i],p,v);
        }else{
            if(i === p){
                o[p]= v;
            }
         }
      }
  };

  // tests if a parameter is an object (and not an array)
  function isObj(o){
      return(typeof o ==='object'&&typeof o.splice!=='function');
  }
      // ... more methods and other code ...
      // make init a public method
  return{
    init:init
  };}();
module.init({
  container:'header','timeout':1000});

当配置对象的所有属性是独特的时这段代码运行的很顺畅.但当属性是嵌套的,上下嵌套层级名字一样是,会失败.为了让这种情况可行.我们可以提供一个选项,发送一个字符串,描述属性的路径.然后就会变的凌乱,我们需要用eval()去解析字符串,确定返回值是正确的格式,所有这些看起来是这样的:

var module =function(){// configuration, change things herevar config ={
    CSS:{
     classes:{
       hover:'hover',
       active:'current',
       jsEnabled:'js'},
     ids:{
       container:'maincontainer'}},
    timeout:2000,
    userID:'chrisheilmann'};

  // start of main code 
  function init(){
      if(isObj(arguments[0])){
          var cfg = arguments[0];
          for(var i in cfg){
              if(i.indexOf('.')!==-1){
                  var str ='["'+ i.replace(/\./g,'"]["')+'"]';
                  var val = getValue(cfg[i]);
                  eval('config'+ str +'='+ val);
              }else{
                  setConfig(config,i,cfg[i]);
              }
          }
       }
   };
function setConfig(o,p,v){
    for(var i in o){
        if(isObj(o[i])){
            setConfig(o[i],p,v);
        }else{
            if(i === p){
                o[p]= v;
             };
        }
    }
};
function isObj(o){
    return(typeof o ==='object'&&typeof o.splice!=='function');
};
function getValue(v){
    switch(typeof v){
    case'string':return"'"+v+"'";break;
    case'number':return v;break;
    case'object':
        if(typeof v.splice==='function'){
            return'['+ v +']';
        }else{
            return'{'+ v +'}';
        }
        break;
    case NaN:break;
    };
};

  // ... more methods and other code ...
  // make init a public method

  return{
    init:init
  };}();

module.init({'container':'header','CSS.classes.active':'now','timeout':1000});

为了更有可读性,让我们封装一下:

var module =function(){// configuration, change things herevar config ={
    CSS:{
     classes:{
       hover:'hover',
       active:'current',
       jsEnabled:'js'},
     ids:{
       container:'maincontainer'}},
    timeout:2000,
    userID:'chrisheilmann'};

  // start of main code 
  function init(){
    console.log(config);
  };

  // ... more methods and other code ...

  // Configuration changes 
  var changeConfig =function(){
      functionset(o){
          var reg =/\./g;
          if(isObj(o)){
              for(var i in o){
                  if(i.indexOf('.')!==-1){
                      var str ='["'+ i.replace(reg,'"]["')+'"]';
                      var val = getValue(o[i]);
                      eval('config'+ str +'='+ val);
                  }else{
                      findProperty(config,i,o[i]);
                  }
              }
        }
};
function findProperty(o,p,v){
    for(var i in o){
        if(isObj(o[i])){
            findProperty(o[i],p,v);
        }else{
            if(i === p){
                o[p]= v;
            };
        }
    }
};
function isObj(o){
    return(typeof o ==='object'&&typeof o.splice!=='function');
};
function getValue(v){
    switch(typeof v){
        case'string':return"'"+v+"'";break;
        case'number':return v;break;
        case'object':
                if(typeof v.splice==='function'){                                               return'['+v+']';}       else{return'{'+v+'}';}break;
        caseNaN:break;
        };
};
    return{
        set:set};
}();
// make init a public method
return{
    init:init
};}();
module.init({'container':'header','CSS.classes.active':'now','timeout':1000});
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值