编写可维护的代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写可维护的代码相关的知识,希望对你有一定的参考价值。

编程风格
1:换行
     一行长度达到单行的最大字符(80字符)限制时,需要手动换行,通常会在运算符后换行,下一行增加俩个层级的缩进。
 
     例子:
          callAfuntion(document,element,window,"some all thing",true,123,
                    navigator)           // 正确
          最后一个字符为运算符“,”
 
2:命名
     函数变量采用驼峰式命名  大驼峰:PassCalss   小驼峰  passCalss
     变量应为名词     函数应为动词(isXXX  canXXX  hasXXX getXXX setXXXX)
     常量:值初始化之后不再变      大写字符_XXXX    (MAX_count)
     构造函数:大驼峰式
          funtion Person(name){
              this.name = name; 
          }
          
          Person.prototpye.sayname = function(){
               return this.name;
          }
     
          var me = new Person("SSSS");
 
3:null
     适用场景:
                    用来初始化可能被赋值成对象的变量
                    用来和一个已经初始化变量比较,变量可以是也可以不是对象
                    当函数的参数期望是对象时,用作参数传入
                    当函数的返回值期望是对象时,用作返回值传出
                   
                         var person = null;
                         
                         function getPerson (){
                              if(condition){
                                  return new Person("SSS"); 
                              }else{
                                  return null;
                             }
                         }
 
                         var person = getPerson();
                         if(person !== null){
                              dosomething();
                         }
     不适用场景:
                    检测是否传入了某参数
                    检测未初始化的变量
 
                         function(arg1,arg2,arg3,arg4){
                              if(arg4 !==null){
                                   doSomethiing();
                              }
                         }
                          
                         var person;
                         if(person !== null){
                              dosomething();
                         }
 
null当做对象的占位符最好
 
4:undefined
     null == undefined   ===>true
     但是  用途是完全不一样的    undefined 是那些未被初始化变量的初始值
 
5:for in  
     用来遍历对象属性     遍历自身的还会遍历从原型继承的属性  避免此情况出现   用 hasOwnProperty判断
          for(var i  in  obj){
               if(obj.hasOwnProperty(i)){
 
               }
          }
 
6:变量提升    提升到包含这段逻辑函数的顶部执行
      function doSomething(){
          var result   =  10 + value;
          var value = 10;
          return result;  // 结果返回    NaN
     }   
     原因js解析成     
     function doSomething(){
          var result;
          var value;
 
          result   =  10 + value;
          value = 10;
          return result;  // 结果返回    NaN
     }  
 
同理   函数也是一样的会提升
 
7:严格模式     “use strict”
     (function(){})();   立即执行
 
8:原始包装类型
     String          Boolean          Number  表示全局作用的一个构造函数  作用:让原始值具有对象般的行为
          var name ="SSS";
          console.log(name.toUpperCase());
 
编程实践
1:不要紧耦合   目标松耦合
     紧耦合就例如     修改.error的css  的名字  还要改html
     松耦合    修改一个组件 而不需要更改其他组件
 
2:将css从javascript抽离
          样式修改时用添加删除类名
     将html 从JavaScript抽离
          模板放置在服务器
          简单模板放置在客户端
 
               使用带自定义type属性的script元素
                    <script type="text/x-my-template" id="list-item">
                         <li><a href="%s">%s</a></li>
                    </script>
                    
                    // var script = document.getElementById("list-item");
                   //  templateText = script.text;
                    
                    function addItem (url,text){
                         var list = document.getElementById("mylist"),
                               script = document.getElementById("list-item"),
                               templateText = script.text,
                               result = sprintf(template,url,text),
                               div = document.createElement("div");
                          
                         div.innerHTML = result.replace(/^\s*/,"");
                         list.appendChild(div.firstChild);
                    }
 
                    addItem("/item/4","fffffff");
               
               如果有问题,也许是模板文本的前导空格导致的
 
          复杂客户端模板    handlebars.js
 
3:全局变量
     尽量避免声明全局的,或使用单全局变量方式
          如:
               var Dd = {};
               
               Dd.Book = function(title){
                    this.title = title; 
                    this.page =1;
               }
 
               Dd.Book.prototype.topage = funciton(dir){
                    this.page+=dir;
               }
 
               Dd.cha1 = new Dd.Book("ddd");
               Dd.cha2 = new Dd.Book("ddsssd");
               Dd.cha3 = new Dd.Book("ddxxd");
 
     命名空间:简单通过全局对象的单一属性表示的功能性分组
     基于单全局变量的扩充方法  使用模块   YUI模块   AMD模块(异步模块)
 
4:事件处理
     规则:
               隔离应用逻辑   (单一函数调用)
                    var Dd = {
                         aa:funciton(e){
                              this.cc(e);
                         },
                         cc:funciton(e){
                             var  p = document.getElementById("p");
                              p.style.left = e.clientX +‘px‘;
                              p.style.top = e.clientY +‘px‘;
                         }
                    }    
                    addListener(element,"click",funciton(e){
                         Dd.aa(e);
                    })    
                   
                    e对象被无节制分发了  错误  不过这样是第一步
                
               不要分发事件对象
                    应用逻辑不应当依赖event对象正确完成功能原因:          
                         方法接口需表明哪些数据是必要的
 
                    var Dd = {
                         aa:funciton(e){
                              this.cc(e.clientX,e.clientY);
                         },
                         cc:funciton(x,y){
                             var  p = document.getElementById("p");
                              p.style.left = x +‘px‘;
                              p.style.top = y +‘px‘;
                         }
                    }    
                    addListener(element,"click",funciton(e){
                         Dd.aa(e);
                    })    
 
5:typeof   检测原始值
     原始值: 字符串     数字     布尔值     null     undefined
     返回:     string     number     boolean     object/null     undefined(未定义的变量,值为undefined的变量)
          不建议用null判断,除非期望返回的是null 
               typeof name
     可用于引用类型Function      返回 function
 
     引用值(除原始值以外的值)
          Object     Array     Date     Error     typeof 返回均object
          检测引用值     instanceof(可检测原型链,自定义类型)
               value instanceof Date
               
               function Aa(name){
                    this.name = name;
               }
               var me = new Aa("dd");
               me instanceof Aa    ----> true
 
     检测类型 优雅方案
          Object.prototype.toString.call(value) === "[object Array]";(自定义对象不用)
 
     属性(是否存在   in)次选 hasOwnProperty()
 
6: 配置数据(hardcoded)应用中写死的  如:
          URL
          需要展示给用户看的字符串
          重复值
          设置(配置项)
          任何可能发现变更的值
               function aa(val){
                    alert(val);     //val  配置数据
                    location.href = "/e/e/e";     //url 配置数据
                    removeClass(element,"class");     //class配置数据
               }
     
     抽离配置数据
          var config ={
               VAL:"value",
               URL:" /e/e/e ",
               CSS_CLASS:"class"
          };
          function aa(val){
                    alert( config.VAL);    
                    location.href = config.URL;     
                    removeClass(element, config.CSS_CLASS);    
               }
     配置数据保存
          1:jSON格式
               {“ss”:"dd", “ss”:"dd", “ss”:"dd", “ss”:"dd"}
          2:JSONP格式
               myfunc( {“ss”:"dd", “ss”:"dd", “ss”:"dd", “ss”:"dd"} )
          3:纯JavaScript格式
               var config = {“ss”:"dd", “ss”:"dd", “ss”:"dd", “ss”:"dd"}
     
7:致力于抛出自定义错误(更加容易的调试,库的开发适用)
          function getDivs(element){
               if(element && element.getElementByTagName){
                    return element.getElementByTagName("div");
               }else{
                    throw new Error("getDivs(): Argument must be a DOM element")
               }
          }
          执行错误可明确知道问题在哪
 
     捕获错误
          try{
               something();
          }catch(ex){
               handleError(ex);
          }
 
8:错误类型
          Error     基础类型
          EvalError     通过eval()函数执行抛出的
          RangeError     数字超出边界
          ReferenceError     期望对象不存在
          SyntaxError     eval()函数有语法错误
          TypeError     变量不是期望的类型
          URIError     encodeURI() encodeURIComponent() decodeURI() decodeURIComponent()等传递非法的URI字符串
          

以上是关于编写可维护的代码的主要内容,如果未能解决你的问题,请参考以下文章

编写可维护的代码

如何编写可维护的 UI 屏幕?

编写可维护的代码示例

豆瓣8.2分:《编写可维护Javascript》

优秀设计之ETC:编写可维护的代码

可维护的Javascript 编写指南