美文网首页饥人谷技术博客
编写可维护的javascript

编写可维护的javascript

作者: jia林 | 来源:发表于2017-08-06 00:21 被阅读0次

每个人都有固定的一套编码习惯,但在团队协作过程中,则需要每个人都遵守统一的编码约定和编程方法。

编程风格

  • 基本的格式化
    1、缩进层级
    (1)不好的习惯

    if( con == ''){
    console.log('是不是分不清层级')}
    else{ console.log('没有主次')}
    

    (2)好的习惯

    if( con == ''){
        console.log('层级很清晰');
    }
    else{ 
        console.log('简单明了');
     }
    

    2、语句结尾
    (1)不好的习惯

    function getVal(){
          return 
          {
              title:'jialin',
              age:23
          }
    }
    //分析器会将他理解为
       function getVal(){
          return; //这样的return返回的是undefined,我们想要的是返回数据对象
          {
              title:'jialin',
              age:23
          }
    }
    

    (2)好的习惯

      function getVal(){
            return  {  //将return和花括号放置一行
                title:'jialin',
                age:23
            }
      }
    

    3、变量和函数的命名

    • 采取小驼峰命名,如:getName,setVal...
    • 命名有意义,体现出类型,如:count、length、size表示数字类型,name、title等表示字符串类型。

    4、null

    • null是一个特殊值,不要将它和undefined高混淆,undefined派生于null,但它们的数据类型不相等
    适用于null的场景
     - 用来初始化一个变量
     - 用来和一个已经初始化的变量比较
     - 当函数的参数期望是对象时,用作参数传入
     - 当函数的返回值期望是对象时,用作返回值传出
    
    不适于null
    - 不要使用null来检测是否传入了某个参数
    - 不要使用null来检测一个未初始化的变量
    
微信截图_20170806001017.png
理解null的最好方式将他当做占位符,对于全局维护性来说至关重要

5、undefined

//不好的写法
var val;
console.log(typeof val);    //undefined
console.log(typeof name); //undefined  会报错, 返回值和typeof容易混淆

以下是我们老大分享的代码规范,在这里分享给你们

js代码规范

文档

JavaScript 文件使用无 BOM 的 UTF-8 编码。
在文件结尾处,保留一个空行。
使用 2 个空格做为一个缩进层级,不允许使用 4 个空格 或 tab 字符。
每个独立语句结束后必须换行。每行不得超过 120 个字符。
运算符处换行时,运算符必须在新行的行首。
// good
if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
    || user.hasAuthority('delete-admin')
) {
    // Code
}

var result = number1 + number2 + number3
    + number4 + number5;


// bad
if (user.isAuthenticated() &&
    user.isInRole('admin') &&
    user.hasAuthority('add-admin') ||
    user.hasAuthority('delete-admin')) {
    // Code
}

var result = number1 + number2 + number3 +
    number4 + number5;
在函数声明、函数表达式、函数调用、对象创建、数组创建、for语句等场景中,不允许在 , 或 ; 前换行。
// good
var obj = {
  a: 1,
  b: 2,
  c: 3
};

foo(
  aVeryVeryLongArgument,
  anotherVeryLongArgument,
  callback
);


// bad
var obj = {
  a: 1
  , b: 2
  , c: 3
};

foo(
  aVeryVeryLongArgument
  , anotherVeryLongArgument
  , callback
);
不同行为或逻辑的语句集,使用空行隔开,更易阅读。
当参数过多时,将每个参数独立写在一行上,并将结束的右括号 ) 独立一行。所有参数必须增加一个缩进。
foo(
  aVeryVeryLongArgument,
  anotherVeryLongArgument,
  callback
);
也可以按逻辑对参数进行组合。

比如angularjs的服务注入,可以将框架提供的服务、自定义服务、常量、提供器分开。

function run(
  $log, $rootScope, $cookies, // 框架内提供
  serverConfig, CONFIG,  // 提供器、常量
  common, sgCommon,  // 自定义服务
);
三元运算符由3部分组成,因此其换行应当根据每个部分的长度不同,形成不同的情况。
var result = thisIsAVeryVeryLongCondition
    ? resultA : resultB;

var result = condition
    ? thisIsAVeryVeryLongResult
    : resultB;
对于 if...else...、try...catch...finally 等语句,推荐使用在 } 号后添加一个换行 的风格,使代码层次结构更清晰,阅读性更好。
if (condition) {
    // some statements;
}
else {
    // some statements;
}

try {
    // some statements;
}
catch (ex) {
    // some statements;
}
不得省略语句结束的分号。
在 if / else / for / do / while 语句中,即使只有一行,也不得省略块 {...}。
// good
if (condition) {
  callFunc();
}

// bad
if (condition) callFunc()
if (condition)
  callFunc()

命名

变量 使用 Camel命名法。
var loadingModules = {};
常量 使用 全部字母大写,单词间下划线分隔 的命名方式。
var HTML_ENTITY = {};
函数 使用 Camel命名法。
function stringFormat(source) {
}
类 使用 Pascal命名法。
function TextNode(options) {
}
枚举变量 使用 Pascal命名法,枚举的属性 使用 全部字母大写,单词间下划线分隔 的命名方式。
var TargetState = {
    READING: 1,
    READED: 2,
    APPLIED: 3,
    READY: 4
};
命名空间 使用 Camel命名法。
equipments.heavyWeapons = {};
类名 使用 名词。
函数名 使用 动宾短语。
function getStyle(element) {
}
boolean 类型的变量使用 is 或 has 开头。
Promise对象 用 动宾短语的进行时 表达。

注释

代码细节注释全部使用行注释,不可使用这样的/*...*/多行注释
为了便于代码阅读和自文档化,以下内容必须包含以 /**...*/ 形式的块注释。
  • 文件
  • namespace
  • 函数或方法
  • 类属性
  • 事件
  • 全局变量
  • 常量
注释中类型说明格式以{开始, 以}结束。

常用类型如:{string}, {number}, {boolean}, {Object}, {Function}, {RegExp}, {Array}, {Date}。

/**
 * 函数描述
 *
 * @param {string} p1 参数1的说明
 * @param {string} p2 参数2的说明,比较长
 *     那就换行了.
 * @param {number=} p3 参数3的说明(可选)
 * @return {Object} 返回值描述
 */
类型定义 语法示例 解释
String {string} --
Number {number} --
Boolean {boolean} --
Object {Object} --
Function {Function} --
RegExp {RegExp} --
Array {Array} --
Date {Date} --
单一类型集合 {Array.<string>} string 类型的数组
多类型 {(number|boolean)} 可能是 number 类型, 也可能是 boolean 类型
允许为null {?number} 可能是 number, 也可能是 null
不允许为null {!Object} Object 类型, 但不是 null
Function类型 {function(number, boolean)} 函数, 形参类型
Function带返回值 {function(number, boolean):string} 函数, 形参, 返回值类型
参数可选 @param {string=} name 可选参数, =为类型后缀
可变参数 @param {...number} args 变长参数, ...为类型前缀
任意类型 {*} 任意类型
可选任意类型 @param {*=} name 可选参数,类型不限
可变任意类型 @param {...*} args 变长参数,类型不限
文件注释

注释添加作者一项

/**
 * @file Describe the file
 * @author xiaozhao@domain.com
 */
命名空间注释
/**
 * 描述
 * @namespace
 */
var util = {};
使用 @class 标记类或构造函数。
/**
 * 描述
 *
 * @class
 */
function Developer() {
    // constructor body
}
使用 @extends 标记类的继承信息。
/**
 * 描述
 *
 * @class
 * @extends Developer
 */
function UserInfoController (){
  BaseController.call(this);
    
  this.init();
}
函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。
参数和返回值注释必须包含类型信息和说明。
/**
 * 函数描述
 *
 * @param {string} p1 参数1的说明
 * @param {string} p2 参数2的说明,比较长
 *     那就换行了.
 * @param {number=} p3 参数3的说明(可选)
 * @return {Object} 返回值描述
 */
function foo(p1, p2, p3) {
    var p3 = p3 || 10;
    return {
        p1: p1,
        p2: p2,
        p3: p3
    };
}
对 Object 中各项的描述, 必须使用 @param 标识。
/**
 * 函数描述
 *
 * @param {Object} option 参数描述
 * @param {string} option.url option项描述
 * @param {string=} option.method option项描述,可选参数
 */
function foo(option) {
    // TODO
}
重写父类方法时, 应当添加 @override 标识。如果重写的形参个数、类型、顺序和返回值类型均未发生变化,可省略 @param@return,仅用 @override 标识,否则仍应作完整注释。
必须使用 @event 标识事件,事件参数的标识与方法描述的参数标识相同。
/**
 * 值变更时触发
 *
 * @event
 * @param {Object} e e描述
 * @param {string} e.before before描述
 * @param {string} e.after after描述
 */
onchange: function (e) {
}
在会广播事件的函数前使用 @fires 标识广播的事件,在广播事件代码前使用 @event 标识事件。
常量注释

常量必须使用 @const 标记,并包含说明和类型信息。

/**
 * 常量说明
 *
 * @const
 * @type {string}
 */
var REQUEST_URL = 'myurl';

变量

变量在使用前必须通过 var 定义,每个 var 只能声明一个变量。变量必须 即用即声明,不得在函数或其它形式的代码块起始位置统一声明所有变量。
在 Equality Expression 中使用类型严格的 ===。仅当判断 null 或 undefined 时,允许使用 == null
尽可能使用简洁的表达式。
// 字符串为空

// good
if (!name) {
    // ......
}

// bad
if (name === '') {
    // ......
}
// 字符串非空

// good
if (name) {
    // ......
}

// bad
if (name !== '') {
    // ......
}
// 数组非空

// good
if (collection.length) {
    // ......
}

// bad
if (collection.length > 0) {
    // ......
}
// 布尔不成立

// good
if (!notTrue) {
    // ......
}

// bad
if (notTrue === false) {
    // ......
}
// null 或 undefined

// good
if (noValue == null) {
  // ......
}

// bad
if (noValue === null || typeof noValue === 'undefined') {
  // ......
}
不要在循环体中包含函数表达式,事先将函数提取到循环体外。
// good
function clicker() {
    // ......
}

for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    addListener(element, 'click', clicker);
}


// bad
for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    addListener(element, 'click', function () {});
}
对循环内多次使用的不变值,在循环外用变量缓存。
类型检测优先使用 typeof。对象类型检测使用 instanceofnullundefined 的检测使用 == null
// string
typeof variable === 'string'

// number
typeof variable === 'number'

// boolean
typeof variable === 'boolean'

// Function
typeof variable === 'function'

// Object
typeof variable === 'object'

// RegExp
variable instanceof RegExp

// Array
variable instanceof Array

// null
variable === null

// null or undefined
variable == null

// undefined
typeof variable === 'undefined'

类型转换

转换成 string 时,使用 + ''
转换成 number 时,通常使用 +
string 转换成 number,要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt

var width = '200px';
parseInt(width, 10);

转换成 boolean 时,使用 !!
number 去除小数点,使用 Math.floor / Math.round / Math.ceil,不使用 parseInt
使用 数组+ 拼接字符串。

for in 遍历对象时, 使用 hasOwnProperty 过滤掉原型中的属性。
遍历数组不使用 for in
不会被调用的依赖模块,在文件开始处统一 require

网络请求

在懒加载、调用接口获取数据时,需要考虑长时间网络延迟的情况下显示加载动画。

相关文章

  • 编写可维护的JavaScript

    基本的格式化 行的长度: 代码但行长度不超过80个字符 换行:超过单行最大字符限制,手动将一行拆成两行,下一行增加...

  • 编写可维护的javascript

    每个人都有固定的一套编码习惯,但在团队协作过程中,则需要每个人都遵守统一的编码约定和编程方法。 编程风格 基本的格...

  • 编写可维护的 JavaScript

    几乎每个程序员都有接手维护别人遗留项目的经历。或者,有可能一个老项目某一天又被重新启动。 通常情况下,接手老项目都...

  • 前端技术书

    入门级 《JavaScript高级程序设计》 《编写可维护的JavaScript》 《Javascript语言精粹...

  • <编写可维护的JavaScript>总结

    第一部分 编程风格 "程序是写给人读的,只是偶尔让计算机运行一下" --- Donald Knuth ...

  • 编写可维护的JavaScript——注释

    注释是代码中最常见的组成部分,他们是另一种形式的文档,也是很重要的一部分。 JavaScript支持两种不同类型的...

  • 编写可维护的JavaScript(二)

    JavaScript 编程的本质是编写一个个的函数来完成任务。在函数内部,变量和运算符可以通过移动操作字节来使某件...

  • 编写可维护的JavaScript(三)

    第七章 事件处理 7.1 隔离应用逻辑 将应用逻辑从事件处理程序中抽离出来 事件处理程序只保留和用户行为相关 7....

  • 编写可维护的JavaScript(一)

    构建软件设计的方法有两种:一种是把软件做得很简单以至于明显找不到缺陷;另一种是把它做得很复杂以至于找不到明显的缺陷...

  • 编写可维护的JavaScript(一)

    《编写可维护的JavaScript》 第一部分 编程风格 1 基本的格式化 1.1 缩进层级 常见的缩进风格有两种...

网友评论

    本文标题:编写可维护的javascript

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