javascript 代码规范

目录

1.为什要遵照代码规范

软件bug的修复是昂贵的,而且随着时间的推移,这些bug的成本也会增长,尤为当这些bug潜伏并慢慢出如今已经发布的软件中时。当你发现bug 的时候就当即修复它是最好的,此时你代码要解决的问题在你脑中仍是很清晰的。不然,你转移到其余任务,忘了那个特定的代码,一段时间后再去查看这些代码就 须要:javascript

  • 花时间学习和理解这个问题
  • 花时间是了解应该解决的问题代码
  • 还有问题,特别对于大的项目或是公司,修复bug的这位伙计不是写代码的那我的(且发现bug和修复bug的不是同一我的)。所以,必须下降理解代 码花费的时间,不管是一段时间前你本身写的代码仍是团队中的其余成员写的代码。这关系到底线(营业收入)和开发人员的幸福,由于咱们更应该去开发新的激动 人心的事物而不是花几小时几天的时间去维护遗留代码。

另外一个相关软件开发生命的事实是,读代码花费的时间要比写来得多。有时候,当你专一并深刻思考某个问题的时候,你能够坐下来,一个下午写大量的代码。css

你的代码很能很快就工做了,可是,随着应用的成熟,还会有不少其余的事情发生,这就要求你的进行进行审查,修改,和调整。例如:html

  • bug是暴露的
  • 新功能被添加到应用程序
  • 程序在新的环境下工做(例如,市场上出现新想浏览器)
  • 代码改变用途
  • 代码得彻底从头从新,或移植到另外一个架构上或者甚至使用另外一种语言

因为这些变化,不多人力数小时写的代码最终演变成花数周来阅读这些代码。这就是为何建立可维护的代码对应用程序的成功相当重要。java

可维护的代码意味着:
  • 可读的
  • 一致的
  • 可预测的
  • 看上去就像是同一我的写的
  • 已记录

2.编写代码需遵照的几个原则

提示: 不遵照这些原则代码也能运行起来。只是可能出现难以维护的现象。规范就像一种模式,你们按照一种模式来,那么阅读其余人的代码,成本就下降了。git

编写代码注意事项:

2.1. 尽可能减小声明全局变量

2.2. 定义变量是,尽可能放到顶部

function func() {
    var a = 1,
        b = 2,
        sum = a + b,
        myobject = {},
        i,
        j;
    // function body...
}

注意:在es6中,使用let 定义,可能出现'暂时性死区', 具体想知道什么叫作'暂时性死区' , 请查看阮一峰 ECMAScript 6 入门es6

2.3.for循环(for Loops)

// 次佳的循环
for (var i = 0; i < myarray.length; i++) {
// 使用myarray[i]作点什么
}
//更好的方式
for (var i = 0, max = myarray.length; i < max; i++) {
// 使用myarray[i]作点什么
}

**JSLint提示您这样作,缘由是++和–-促进了“过度棘手(excessive trickiness)”。//zxx:这里比较难翻译,我想本意应该是让代码变得更加的棘手
若是你直接无视它,JSLint的plusplus选项会是false(默认是default)。**github

还有两种变化的形式,其又有了些微改进,由于:正则表达式

  • 少了一个变量(无max)
  • 向下数到0,一般更快,由于和0作比较要比和数组长度或是其余不是0的东西做比较更有效率

    //第一种变化的形式:
    var i, myarray = [];
    for (i = myarray.length; i–-;) {
    // 使用myarray[i]作点什么
    }api

    //第二种使用while循环:数组

    var myarray = [],
    i = myarray.length;
    while (i–-) {
    // 使用myarray[i]作点什么
    }

面两种状况优于前面两种状况。

2.4.for-in循环(for-in Loops)

for-in循环应该用在非数组对象的遍历上,使用for-in进行循环也被称为“枚举”。

从技术上将,你可使用for-in循环数组(由于JavaScript中数组也是对象),但这是不推荐的。由于若是数组对象已被自定义的功能加强,就可能发生逻辑错误。另外,在for-in中,属性列表的顺序(序列)是不能保证的。因此最好数组使用正常的for循环,对象使用for-in循环。

有个很重要的hasOwnProperty()方法,当遍历对象属性的时候能够过滤掉从原型链上下来的属性

// 对象
var man = {
    hands: 2,
    legs: 2,
    heads: 1
};

// 在代码的某个地方
// 一个方法添加给了全部对象
if (typeof Object.prototype.clone === "undefined") {
    Object.prototype.clone = function () {};
}
====================================================================
// for-in 循环
for (var i in man) {
if (man.hasOwnProperty(i)) { // 过滤
    console.log(i, ":", man[i]);
}
}
/* 控制台显示结果
hands : 2
legs : 2
heads : 1
*/
==========================================================================
// 反面例子:
// for-in loop without checking hasOwnProperty()
for (var i in man) {
console.log(i, ":", man[i]);
}
/*
控制台显示结果
hands : 2
legs : 2
heads : 1
clone: function()
*/

2.5.(不)扩展内置原型((Not) Augmenting Built-in Prototypes)

增长内置的构造函数原型(如Object(), Array(), 或Function())挺诱人的,可是这严重下降了可维护性,由于它让你的代码变得难以预测。使用你代码的其余开发人员极可能更指望使用内置的 JavaScript方法来持续不断地工做,而不是你另加的方法。

所以,不增长内置原型是最好的。你能够指定一个规则,仅当下面的条件均知足时例外:

  • 能够预期未来的ECMAScript版本或是JavaScript实现将一直将此功能看成内置方法来实现。例如,- 你能够添加ECMAScript 5中描述的方法,一直到各个浏览器都迎头遇上。这种状况下,你只是提早定义了有用的方法。
  • 若是您检查您的自定义属性或方法已不存在——也许已经在代码的其余地方实现或已是你支持的浏览器JavaScript引擎部分。
  • 你清楚地文档记录并和团队交流了变化。

    if (typeof Object.protoype.myMethod !== "function") {
           Object.protoype.myMethod = function () {
               // 实现...
           };
       }

通常状况下,强烈不建议使用

2.6.避免隐式类型转换(Avoiding Implied Typecasting )

JavaScript的变量在比较的时候会隐式类型转换。这就是为何一些诸如:false == 0 或 “” == 0 返回的结果是true。为避免引发混乱的隐含类型转换,在你比较值和表达式类型的时候始终使用===和!==操做符。

var zero = 0;
if (zero === false) {
// 不执行,由于zero为0, 而不是false
}

// 反面示例
if (zero == false) {
// 执行了...
}

2.7. 避免(Avoiding) eval()

若是你如今的代码中使用了eval(),记住该咒语“eval()是魔鬼”。此方法接受任意的字符串,并看成JavaScript代码来处理。当有 问题的代码是事先知道的(不是运行时肯定的),没有理由使用eval()。若是代码是在运行时动态生成,有一个更好的方式不使用eval而达到一样的目 标。例如,用方括号表示法来访问动态属性会更好更简单:

// 反面示例
var property = "name";
alert(eval("obj." + property));

// 更好的
var property = "name";
alert(obj[property]);

3.编码规范

3.1 缩进(Indentation)

代码没有缩进基本上就不能读了。惟一糟糕的事情就是不一致的缩进,由于它看上去像是遵循了规范,可是可能一路上伴随着混乱和惊奇。重要的是规范地使用缩进。

一些开发人员更喜欢用tab制表符缩进,由于任何人均可以调整他们的编辑器以本身喜欢的空格数来显示Tab。有些人喜欢空格——一般四个,这都无所谓,只要团队每一个人都遵循同一个规范就行了。这本书,例如,使用四个空格缩进,这也是JSLint中默认的缩进。

什么应该缩进呢?规则很简单——花括号里面的东西。这就意味着函数体,循环 (do, while, for, for-in),if,switch,以及对象字面量中的对象属性。下面的代码就是使用缩进的示例:

function outer(a, b) {
    var c = 1,
        d = 2,
        inner;
    if (a > b) {
        inner = function () {
            return {
                r: c - d
            };
        };
    } else {
        inner = function () {
            return {
                r: c + d
            };
        };
    }
    return inner;
}

3.2 花括号{}(Curly Braces)

// 糟糕的实例
for (var i = 0; i < 10; i += 1)
alert(i);
// 好的实例
for (var i = 0; i < 10; i += 1) {
alert(i);
}

3.3 左花括号的位置(Opening Brace Location)

这个实例中,仁者见仁智者见智,但也有个案,括号位置不一样会有不一样的行为表现。这是由于分号插入机制(semicolon insertion mechanism)——JavaScript是不挑剔的,当你选择不使用分号结束一行代码时JavaScript会本身帮你补上。这种行为可能会致使麻 烦,如当你返回对象字面量,而左括号却在下一行的时候

// 警告: 意外的返回值
function func() {
    return
    // 下面代码不执行
    {
        name : "Batman"
    }
}

// 警告: 意外的返回值
function func() {
    return undefined;
    // 下面代码不执行
    {
        name : "Batman"
    }
}

3.4 空格(White Space)

空格的使用一样有助于改善代码的可读性和一致性。在写英文句子的时候,在逗号和句号后面会使用间隔。在JavaScript中,你能够按照一样的逻辑在列表模样表达式(至关于逗号)和结束语句(相对于完成了“想法”)后面添加间隔。

适合使用空格的地方包括:
  • for循环分号分开后的的部分:如for (var i = 0; i < 10; i += 1) {...}
  • for循环中初始化的多变量(i和max):for (var i = 0, max = 10; i < max; i += 1) {...}
  • 分隔数组项的逗号的后面:var a = [1, 2, 3];
  • 对象属性逗号的后面以及分隔属性名和属性值的冒号的后面:var o = {a: 1, b: 2};
  • 限定函数参数:myFunc(a, b, c)
  • 函数声明的花括号的前面:function myFunc() {}
  • 匿名函数表达式function的后面:var myFunc = function () {};

使用空格分开全部的操做符和操做对象是另外一个不错的使用,这意味着在+, -, *, =, <, >, <=, >=, ===, !==, &&, ||, +=等先后都须要空格。

// 宽松一致的间距
// 使代码更易读
// 使得更加“透气”
var d = 0,
    a = b + 1;
if (a && b && c) {
    d = a % c;
    a += d;
}

// 反面例子
// 缺失或间距不一
// 使代码变得疑惑
var d = 0,
    a = b + 1;
if (a&&b&&c) {
    d=a % c;
    a+= d;
}

最后须要注意的一个空格——花括号间距。最好使用空格:

  • 函数、if-else语句、循环、对象字面量的左花括号的前面({)
  • else或while之间的右花括号(})

    //{} 空格
    if (4) {
    console.log(1)
    } else if (3) {
    console.log(1)
    }
    var a = {}

4.命名规范

  • 另外一种方法让你的代码更具可预测性和可维护性是采用命名规范。这就意味着你须要用同一种形式给你的变量和函数命名。
  • 下面是建议的一些命名规范,你能够原样采用,也能够根据本身的喜爱做调整。一样,遵循规范要比规范是什么更重要。

4.1以大写字母写构造函数(Capitalizing Constructors)

JavaScript并无类,但有new调用的构造函数:

var adam = new Person();

由于构造函数仍仅仅是函数,仅看函数名就能够帮助告诉你这应该是一个构造函数仍是一个正常的函数。
命名构造函数时首字母大写具备暗示做用,使用小写命名的函数和方法不该该使用new调用:

function MyConstructor() {...}
function myFunction() {...}、

4.2 分隔单词(Separating Words)

当你的变量或是函数名有多个单词的时候,最好单词的分离遵循统一的规范,有一个常见的作法被称做“驼峰(Camel)命名法”,就是单词小写,每一个单词的首字母大写。

  • 对于构造函数,可使用大驼峰式命名法(upper camel case),如MyConstructor()。
  • 对于函数和方法名称,你可使用小驼峰式命名法(lower camel case),像是myFunction(), calculateArea()和getFirstName()。

## 4.3 注释(Writing Comments)

你必须注释你的代码,即便不会有其余人向你同样接触它。一般,当你深刻研究一个问题,你会很清楚的知道这个代码是干吗用的,可是,当你一周以后再回来看的时候,想必也要耗掉很多脑细胞去搞明白到底怎么工做的。

很显然,注释不能走极端:每一个单独变量或是单独一行。可是,你一般应该记录全部的函数,它们的参数和返回值,或是任何不寻常的技术和方法。要想到注 释能够给你代码将来的阅读者以诸多提示;阅读者须要的是(不要读太多的东西)仅注释和函数属性名来理解你的代码。例如,当你有五六行程序执行特定的任务, 若是你提供了一行代码目的以及为何在这里的描述的话,阅读者就能够直接跳过这段细节。没有硬性规定注释代码比,代码的某些部分(如正则表达式)可能注释 要比代码多。

5.css代码规范

css规范咱们伟大的张旭鑫老师,讲的很清楚。面向属性的命名

这是比较好的命名规范。简介来讲,就是咱们先定义好一些经常使用基础类样式。组件则使用less,或者sass进行组装,造成便可。

相关文章
相关标签/搜索