[笔记]最佳实践

最佳实践将分为三大方面讲述:1.可维护性、2.性能、3.部署javascript

参考《JavaScript高级程序设计》总结出如下内容:php

1.可维护性

1.1什么是可维护的代码?

可维护的代码遵循如下特色:java

  1. 可理解性:其余人能够接手代码并理解它的意图和通常途径,而无需开发人员的完整解释。
  2. 直观性:代码中的东西一看就能明白,无论其操做过程多么复杂。
  3. 可适应性:代码以一种数据上的变化不要求彻底重写的方法撰写。
  4. 可拓展性:在代码架构上已考虑到在将来容许对核心功能进行扩展。
  5. 可调试性:当有地方出错时,代码能够给予你足够的信息来尽量直接的肯定问题所在。

1.2 代码约定

1.可读性:可维护的前提是必须可读,因此可读性是很重要的,主要两方面改善可读性:缩进,注释。算法

通常而言如下地方须要进行注释:编程

一、函数和方法数组

二、大段代码bash

三、复杂的算法架构

四、Hack函数

2.变量和函数命名性能

适当给变量和函数起名字对于增长代码可理解性和可维护性是很是重要的。

命名规则以下:

  • 变量名应为名词如car或person
  • 函数名应该以动次开始,如getName()。返回布尔类型值的函数通常以is开头,如isEnable()。
  • 变量和函数都应使用合乎逻辑的名字,不要担忧长度。长度问题能够经过后处理和压缩来缓解。

3.变量类型透明

JavaScript中变量类型是松散类型的,因此很容易就忘记变量所应包含的数据类型。合适的命名方式能够必定程度上缓解这个问题,但放到全部的状况下看,还不够。有三种表示变量数据类型的方式。

第一种方式是初始化。当定义了一个变量后,他应该被初始化为一个值,来暗示他未来应该如何应用,例如:

var found = false;          //布尔型
var count = -1;             //数字
var name  = '';             //字符串
var person= null;           //对象复制代码

初始化为一个特定的数据类型能够很好的指明变量的类型,但缺点是他没法用于函数声明中的参数。

第二种方法是使用匈牙利标记法来指定变量类型。例如:

var bFound;     //布尔型
var iCount;     //整数
var sName;      //字符串
var oPerson;    //对象复制代码

最后一种方法是使用类型注释。类型注释放在变量名右边。以下所示:

var found /*:Boolean*/ = false;
var count /*:int*/     = 10;
var name  /*:String*/  = 'nicholas';
var person /*:Object*/ = null;复制代码

缺点是不能用多行注释一次注释大块的代码。


1.3 松散耦合

只要应用的某个部分过度依赖于另外一部分,代码就是耦合过紧,男与维护。典型的问题如:对象直接引用另外一个对象,而且当修改其中一个的同时须要修改另一个。紧密耦合的软件难于维护而且须要常常重写。

1.解耦HTML/JavaScript

尽可能避免的紧密耦合状况:

一、直接写在HTML中的JavaScript

二、使用事件处理程序属性值的紧密耦合的HTML/javascript

三、在JavaScript中建立大量HTML。

理想的状况是,HTL和JavaScript应该彻底分离,而且经过外部文件和使用DOM附加行为来包含JavaScript。


2.解耦CSS/JavaScript

现代Web开发免不了要用JavaScript改变某些样式,可是未来若是须要更改样式表,CSS和JavaScript文件可能都须要更改。这会对开发人员形成心理阴影...因此在这两个层次之间必须有清晰的划分。

但也是有解决方法的:经过更改样式类而非特定样式。


3.解耦应用逻辑/事件处理程序


1.4 编程实践

1.尊重对象全部权

意思是你不能修改不属于你的对象。更具体的说:

  • 不要为实例或原型添加属性;
  • 不要为实例或原型添加方法;
  • 不要重定义已存在的方法。

只要对象不是本身建立的,就永远不去修改,明显Array、document这些对象都不是你的,它们在你的代码执行前就存在了。可是依然能够经过如下方式为对象建立新的功能:

  • 建立包含所需功能的新对象,并用它与相关对象进行交互;
  • 建立自定义类型,继承须要进行修改的类型,而后能够为自定义类型添加额外功能。


2.避免全局变量

3.避免与null进行比较

4.使用常量

尽管JavaScript没有常量的正是概念,但它仍是颇有用的。这种将数据从应用逻辑分离出来的思想,能够在不冒引入错误的风险的同时,就改变数据。请看如下例子:

function validata(value){
    if(!value){
        alert('Invalid value!');
        location.href = '/errors/invalid.php';
    ]
}复制代码

这个函数中有两段数据:要显示给用户的信息以及URL。显示在用户界面上的字符串应该以容许进行语言国际化的方式抽取出来。URL也应该被抽取出来,由于它们有随着应用成长而改变的倾向。 基本上,有着可能因为这样那样缘由会变化的这些数据,那么都会须要找到函数并在其中修改代码。而每次修改应用逻辑的代码,均可能会引入错误。能够经过将数据抽取出来变成单独定义的常量的方式,将应用逻辑与数据修改隔离开来。例如:

var Constants = {
    INVALID_VALUE_MSG: 'Invalid value!',
    INVALID_VALUE_URL: '/errors/invalid.php'
};

function validata(value){
    if (!value){
        alert(Constants.INVALID_VALUE_MSG);
        location.href = Constants.INVALID_VALUE_URL;
    }
};复制代码

在这段重写过的代码中,消息和URL都被定义于Constants对象中,而后函数引用这些值。这些设置容许数据在无需使用它的函数的状况下进行变动。Constants对象甚至能够在彻底独立的文件中定义,同时该文件能够由包含正确值的其余过程根据国际化设置来生成。

关键在于将数据和使用它的逻辑进行分离。要注意的值的类型以下所示。

重复值:任何在多出用到的值都应该抽取为一个常量,这就限制了当一个值变了而另外一个没变的时候会形成的错误。这也包含了CSS类名。

用户界面字符串:任何用户显示给用户的字符串,都应被抽取出来以方便国际化。

URLs:在Web应用中,资源位置很容易变动,因此推荐一个公共地方存放全部的URL。

任意可能会更改的值:每当你在用到字面量值的时候,你都要问一下本身这个值在将来是否是会变化。若是答案是‘是’,那么这个值就应该被提取出来做为一个常量。

对于企业级的JavaScript开发而言,使用常量是很是重要的技巧,由于他能让代码更容易维护,而且在数据更改的同时保护代码。


2.性能

2.1 注意做用域

只要能减小化肥在做用域链上的事件,就能增长脚本的总体性能。

1.避免全局查找

2.避免with语句


2.2 选择正确方法

1.避免没必要要的属性查找。

属性查找越多,执行时间就越长。

通常来说,只要能减小算法的复杂度,就要尽量减小。尽量多地使用局部变量将属性查找替换为值查找。

2.优化循环

循环的基本优化步骤以下所示:

  1. 减值迭代:大多数循环使用一个从0开始、增长到某个特定值的迭代器。在不少状况ixa、从最大值开始,在循环中不断减值的迭代器更加高效。
  2. 简化终止条件:因为每次循环过程都会计算终止条件,因此必须保证它尽量快。也就是说避免属性查找或其余O(n)的操做。
  3. 简化循环体:循环体是执行最多的,因此要确保其被最大限度的有话啊。确保没有某些能够被很容易移出循环的密集计算。
  4. 使用后测试循环:do-while

3.展开循环

当循环的次数是肯定的,消除循环并使用屡次函数调用每每更快。

针对大数据集使用展开循环能够节省不少时间,但对于小数据集,额外的开销则可能得不偿失。它是要花更多的代码来完成一样的任务,若是处理的不是大数据集,通常来讲并不值得。

4.避免双重解释

5.性能的其余注意事项

  • 原生方法较快:只要有可能,使用原生方法而不是本身用JavaScript重写一个。
  • switch语句较快:若是有一系列复杂的if-else语句,能够转换成单个switch语句则能够获得更快的代码。 还能够经过将case语句按照最可能的到最不可能的顺序进行组织,来进一步优化switch语句。
  • 位运算符较快


2.3 最小化语句数

JavaScript代码中的语句数量也影响所执行的操做的速度。完成多个操做的单个语句要比完成单个操做的多个语句快。因此就要找出能够组合在一块儿的语句,以减小脚本总体的执行时间。

1.多个变量声明

多个变量的声明尽可能用一个语句。例如

//4个语句-很浪费
var count = 5;
var color = 'blue';
var values = [1,2,3];
var now = new Date();复制代码

重写以下:

var count = 5,
    color = 'blue',
    values = [1,2,3],
    now = new Date();
复制代码

2.插入迭代值

当使用迭代值的时候,尽量合并语句。请看代码:

var name = values[i];
i++;复制代码

优化后

var name = values[i++];复制代码

3.使用数组和对象字面量(不用构造函数)

使用构造函数老是要用到更多的语句来插入元素或者定义属性,而字面量能够将这些操做在一个语句中完成。例如:

//用4个语句建立和初始化数组 - 浪费
var values = new Array();
values[0] = 123;
values[1] = 456;
values[2] = 789;

//用4个语句建立和初始化对象 - 浪费
var person = new Object*(;
person.name = 'nicholas';
person.age = 29;
person.sayName = function(){
    alert(this.name);
};复制代码

重写:

//只用一条语句建立和初始化数据
var values = [123,456,789];

//只用一条语句建立和初始化对象
var person = {
    name : 'nicholas',
    age : 29,
    sayName : function(){
        alert(this.name);
    }
};复制代码

只要有可能,尽可能使用数组和对象的字面量表达方式来消除不要的语句。


2.4 优化DOM交互

在JavaScript的各方面中,DOM毫无疑问是最慢的一部分。

因此优化DOM交互是极其重要的,下面是关于DOM优化的总结:

1.最小化现场更新:尽可能一次性把DOM元素添加成功,添加的操做(现场更新)越少越好。

2.使用innerHTML:innerHTML方法会在后台建立一个HTML解析器,而后使用内部的DOM调用来建立DOM,而非基于JavaScript的DOM调用。因为内部方法是编译好的而非解释执行的,因此执行快得多。

3.使用事件代理

4.注意HTMLCollection:最小化访问HTMLCollection的次数能够极大地改进脚本的性能。例如:

var images = document.getElementsByTagName('img'),
    i,len;
for(i=0,len=images.length;i<len;i++){
    //处理
}复制代码

这里的关键在于长度length存入了len变量,而不是每次都去访问HTMLCollection的length属性,当在循环中使用HTMLCollection的时候,下一步应该是获取要使用的项目的引用,以下所示,一边避免在循环体内屡次调用HTMLCollection

var images = document.getElementsByTagName('img'),
    image,
    i,len;
for(i=0,len=images,length;i<len;i++){
    image = images[i];
    //处理
}复制代码

这段代码添加了image变量,保存了当前的图像,这以后在循环内疚没有理由在访问images的HTMLCollection了。

发生如下状况时会返回HTMLCollection对象:

  1. 进行了对getElementsByTagName()的调用;
  2. 获取了元素的childNodes属性;
  3. 获取了元素的attributes属性;
  4. 访问了特殊的集合,如document.forms/document.images等。



以上。

相关文章
相关标签/搜索