文档章节

[JS进阶] 编写可维护性代码

赵小宾
 赵小宾
发布于 2015/04/01 10:11
字数 2455
阅读 117
收藏 9
点赞 0
评论 0
Js

1 可维护性代码的特点

  1. 可理解性:其他人可以接手代码并理解它的意图,无需原开发人员花太多时间解释!
  2. 直观性:代码中的东西一看就能明白,尽管其操作过程复杂。
  3. 可适应性:代码以一种数据上的变化不要求完全重写方法。
  4. 可扩展性:在代码架构上可对核心功能的扩展。
  5. 可调式性:出错时,代码可以给你足够的信息来直接确定问题所在。

2 代码约定

由于javascript语言的特点,我们可编写各种编程风格的代码,从传统的面向对象式到声明式到函数式。形成一套良好的javascript代码书写约定可大大提高可维护性,这点对初学者来说绝对是没有很注重的地方。

2.1 可读性

  1. 缩进:在项目中统一代码缩进,更易于阅读,一种不错也很常见的缩进大小为四个空格,当然可以是其他数量。
  2. 注释:其实我们在编写一些后台代码会经常把一个功能,一个业务逻辑,一个函数的代码注释起来,但我们却在编写javascript却经常忽略这些习惯。一般而言,在js中有以下这些地方需要注释:
  • 函数和方法 :描述其目的和参数代表,返回值等。
  • 大段的代码 :大段代码通常是一个任务的代码,应注释描述任务。
  • 复杂的算法 :不是所有人都会你的算法,你需要把你的算法思路简单描述下。
  • Hack :因各浏览器的差异,javascript的hack用于解决什么问题应该描述清楚。

2.2 变量和函数的命名

  1. 变量名应该名词:如car,person
  2. 函数名应以动词开始:如getName(),返回布尔类型值的函数一般以is开头,如:isEnable();
  3. 只要合乎逻辑,不用担心变量或者函数名的长度,长度问题可以通过在你发布代码压缩的时候得以解决。

2.3 变量类型透明

var car,person; //声明两个变量

如上代码,由于javascript中变量是松散类型的,我们并不知道其中的car和person是什么类型的数据,不够透明,我们可以通过一下两种方式缓解这种问题:

  1. 初始化变量:通过初始化指定变量类型,但通过这种方式命名的对象无法用于函数声明中的参数。

    var car = null; //car是对象 var person = ''; //person是字符串 var count = -1; //count是整数 var found = false; //found是布尔型
  2. 匈牙利标记法:在变量名之前加上一个或多个字符表示数据类型。o - 对象,s - 字符串,i - 整数,f - 浮点数,b - 布尔型

    var oCar; //car是对象 var sPerson; //person是字符串 var iCount; //count是整数 var bFound; //found是布尔型

3 松散耦合

记得以前刚入门C#的时候,师兄经常跟我说‘高内聚低耦合’这词,我也就含糊地点点头,很多人可能也像我之前一样,这词耳熟能详,但未真正实践。

只要应用的某个部分过分依赖另一部分,代码就是耦合过紧,难于维护! 典型的问题:对象直接应用另一个对象,并且修改其中一个的同时需要修改另一个。 在我们web应用中,我们可以通过一下方式解耦我们的代码:

3.1 解耦HTML/JavaScript

在web应用中,我们希望html专注于展示数据,css专注于样式,javascript专注于行为交互。但是有一些代码会将html、javascript过于紧密地耦合在一起。

  1. 直接写在HTML中javascript,使用包含内联代码的<script>元素或者是使用HTML属性来分配事件处理程序。

    <!--使用<script>标签的紧密耦合 --> <script type="text/javascript"> document.write('hello,javascript'); </script> <!--使用时间处理程序属性值的紧密耦合 --> <input type="button" value="click me" onclick="doSomething()"/>

    虽然这样写完全正确,但出现javascript错误是,我们需要判断错误出现在HTML还是在Javascript中,并且这还存在一个时间差问题,当我按下上面代码的按钮时,若此时javascript代码并未加载完,此时变回引发错误。在实践中,理想的状况应该是HTML和Javascript应完全分离,使用引入外部文件来加载javascript。

  2. 相反地,在javascript中也不能包含过多的HTMl

    function insertMsg(msg){ var container = document.getElementById('container');
        container.innerHtml = '<div lcass=\"msg\"><p class=\"post\">' + msg + '</p></div>' }

当你在写这样的代码的时候,我想你应该去找个js模板引擎来了。

对动态生成的HTML,对书写CSS布局,定位错误都比较难把控。

3.2 解耦CSS/Javascript

上面说了,CSS和JS都应该各司其职,不能有太大的亲密动作,秀恩爱,死得快 囧~~~。
这个问题并不能说完全解耦css和js,因为在现代web应用中常常需要javascript来更改样式,但是我们还是尽量使他们分离。

// CSS对JS的紧密耦合 element.style.color = 'red';
element.style.backgroundColor= 'blue';

这样的代码在以后修改样式的时候需要同时修改CSS和JS,可麻烦了。

//这样就ok了 element.className = 'color'; //color是样式类

还有一个就是不能在CSS中写CSS表达式,这应该是都知道的了。

3.3 解耦应用逻辑和事件处理程序

每个web应用程序都有相当多的事件处理程序,监听着大量不同的事件,然而,很少能有仔细将应用逻辑从事件处理程序中分离的,如下:

function checkValue(e){
   e = e || window.event; var target = e.target || e.srcElement; if(target.value.length < 5){ //省略一堆逻辑处理代码... }
}

将上面的代码重写为:

function checkValue(value){ if(value.length < 5){ //省略一堆逻辑处理代码... }
   } function handleBlur(e){
       e = e || window.event; var target = e.target || e.srcElement;
       checkValue(target.value); //调用应用逻辑处理函数 }

这样写有什么好处呢?

  1. 当有不同的方式触发相同的相同过程事件的时候,这时只需调用应用逻辑处理函数即可。
  2. 应用逻辑处理函数可以在不添加到事件的情况下单独测试。

4 编程实践

在企业环境中创建的web应用往往同时由大量人员一同创作。在这种情况下的目标是确保每个人所使用的浏览器环境都有一致和不变的规则,因此,我们需要坚持一下的一些编程实践:

4.1 避免全局变量

在一个js文件中,最多允许有一个全局变量,让其他对象和函数包含在其中,因为过多的全局变量会消耗大量内存。

//两个全局变量 var name = 'jozo'; function sayName(){
  alert('jozo');
}

上面的代码有两个全局变量,变量name和函数sayName(),其实可以创建一个变量包含它们:

//一个全局变量 --推荐 var person = {
    name:'jozo',
    sayName : function(){
        alert(this.name);
    }
}

这样一个全局变量延伸开来就是‘空间的概念’了,不会与其他功能产生冲突,有助于消除功能作用域之间的混淆。

4.2 避免与null进行比较

function sortArray(values){ if(values != null){
        values.sort(比较函数);
    }
}

上面代码中的if语句应该检测values是否是数组,但如果与null作比较的话,字符串,数字等都会通过,导致函数抛出错误。这里是数组,那么我们就应该检测其是否为数组:

function sortArray(values){ if(values instanceof Array){
        values.sort(比较函数);
    }
}

所于当我们遇到与null作比较的代码的时候,我们应该用下面的技术替换:

  1. 如果值为引用类型,则用instanceof 操作符检查其构造函数。
  2. 如果值是基本类型,则用typeof操作符检查其类型。

4.3 使用常量

function validate(value){ if(!value){
        alert('不存在');
        location.href = '/errors/invalid.php';
    }
}

现在,我想把‘不存在’改为‘该数据不存在!’,把跳转路径也改了,我得回到函数中找到对应的代码去修改,而每次修改逻辑代码,都有可能引入错误的风险。所以我们可以把数据单独定义为常量,与应用逻辑分离:

var Constans = {
    ERRORMSG: '不存在',
    ERRORPAGE:'/errors/invalid.php' }; function validate(value){ if(!value){
        alert(Constans.ERRORMSG );
        location.href = Constans.ERRORPAGE ;
    }
}

这样我们修改静态文本内容的时候就无需去动逻辑函数了,甚至可以把Constans单独一个文件。那么什么样的数据需要抽出来做常量呢?

  1. 重复值:任何在多处用到的值。
  2. 用户界面字符串:任何用于显示给用户提示信息的字符串。
  3. URLs:在WEB项目中,资源路径可能经常变更。在一个公共的地方存起来,修改起来更容易!
  4. 任何可能在以后会改变的值。

5 总结

所有编程语言都需要可维护性良好的代码,这个很重要,因为大部分开发人员都花费大量时间维护他人的代码。为了减轻相互的负担,从今天起我要做个好人,写好代码! o(╯□╰)o

© 著作权归作者所有

共有 人打赏支持
赵小宾
粉丝 7
博文 54
码字总数 8001
作品 0
浦东
学习Javascript的8张思维导图

分别归类为:  javascript变量  javascript运算符  javascript数组  javascript流程语句  javascript字符串函数  javascript函数基础  javascript基础DOM操作  javascript正则表达式...

thinkyoung ⋅ 2014/09/23 ⋅ 0

python_day14_前端_JS-重写

说明 ECMA(欧洲计算机制造协会)   ECMA(欧洲计算机制造协会)定义了ECMA-262规范.国际标准化组织及国际电工委员会(ISO/IEC)也采纳 ECMAScript 作为标准(ISO/IEC-16262)。从此,Web 浏览...

812374156 ⋅ 05/25 ⋅ 0

JavaWeb01-HTML篇笔记(七)

.1 案例三:完成对注册页面的数据的简单校验.1.1.1 需求: 对注册页面的数据进行非空的简单校验!!!如果有某个值没有输入,点击提交,弹出一个对话框进行提示!! 1.1.2 分析:1.1.2.1 技术分...

我是小谷粒 ⋅ 04/28 ⋅ 0

细谈在HTML中使用JavaScript

细谈在HTML中使用JavaScript 前言 JavaScript是浏览器的内置脚本语言。当网页中嵌入了JavaScript脚本,浏览器加载网页时,就会执行脚本,从而操作浏览器,实现各种动态效果 JavaScript代码嵌...

幸运券发放 ⋅ 05/25 ⋅ 0

深入浅出JS - 变量提升(函数声明提升)

前言 在我们的日常工作中,变量无处不在。更加深入的去了解它,能够使得自己的JS水平更上一层楼, 从变量提升这个小知识点着手,让我们一起来深入了解JS吧! 变量提升的小栗子 分析原因 JS引...

秋秋秋丷 ⋅ 05/17 ⋅ 0

前端学习之路(从入门到入坑...)

学习前端两年多了,拿了阿里巴巴实现offer,想结合个人经历总结的前端入门方法,总结从零基础到具备前端基本技能的道路、学习方法、资料。由于能力有限,不能保证面面俱到,只是作为入门参考...

阿小庆 ⋅ 06/14 ⋅ 0

JavaScript中的this指针 理论化this指针的定义

JavaScript现在应用之广泛,远超其他任何语言,只要是一个合格的网站应用,基本上多多少少都会有JS的存在。在JavaScript中,this的指向被不少Coder所不解,但其实JS中的this理解起来也是相当...

superwebmaster ⋅ 05/29 ⋅ 0

五月前端知识集锦(每月不可错过的文章集锦)

目前自己组建的一个团队正在写一份面试图谱,将会在七月中旬开源。内容十分丰富,第一版会开源前端方面知识和程序员必备知识,后期会逐步写入后端方面知识。因为工程所涉及内容太多(目前已经...

夕阳 ⋅ 05/28 ⋅ 0

JavaScript 编程精解 中文第三版 零、前言

零、前言 原文:Introduction 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript 编程精解(第 2 版)》 We think we are creating the system for our own purp...

ApacheCN_飞龙 ⋅ 06/01 ⋅ 0

将一个前端项目改写为chromo插件(一)

编写第一个chrome插件? 编写chrome插件完全就是前端知识加上一些专门的知识。 假设文件夹下有文件 嗯,现在看来他只是普通的html,其实,你只要在当前文件夹下加上文件,chrome浏览器就可以把...

saltfish666 ⋅ 05/27 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 2

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部