写更好的JavaScript

起因

  最近项目不是很忙,开始填前一段时间遗留的坑,前一段时间添加好多的功能,预留的时间周期比较短,写的代码也是千奇百怪,娥娜多姿呀!下面来那一些不好的代码分析一下.

分析哪些被我们写坏的代码

  从两方面说:

  1. 全局查找
  2. DOM交互

全局查找 不好的实例

//在函数中,有5个对全局对象document的引用,意味着5次从document中查找元素
function zoom() {
	document.getElementById("planePic1").width = document.getElementById("planePic1").width * 2;
	document.getElementById("planePic1").height = document.getElementById("planePic1").height * 2;
	document.getElementById("plane2").style.display = "none";
}

全局查找 好的实例

//在函数中,将全局对象document缓存到变量doc中,只需一次全局查找
function zoom() {
    var doc = document;
    doc.getElementById("planePic1").width = doc.getElementById("planePic1").width * 2;
    doc.getElementById("planePic1").height = doc.getElementById("planePic1").height * 2;
    doc.getElementById("plane2").style.display = "none";
}

dom交互 不好的实例

//循环几次,就往元素添加几个option,与dom频繁交互,会导致浏览器重绘(redraw)和重排(reflow)
var select = $('#selectOffice');
select.empty();
var option;
for (index in data) {
    option = data[index];
    select.append("<option value='" + option.NID + "' title='" + option.SNAME + "'>" + option.SNAME + "</option>");
}

dom交互 好的实例

//方式一 过字符串拼接
//一次添加到元素中,避免了与dom多次交互
var select = $('#selectOffice');
var optionStr = '';
for (var i = 0, len = data.length; i < len; i++) {
    optionStr += '<option value="' + data[i].NID + '" title="' + data[i].SNAME + '">' + data[i].SNAME + '</option>';
}
select.html(optionStr);


//方式二 使用文档片段来构建dom结构
var doc = document;
var element = doc.createDocumentFragment();
var selectOffice = doc.getElementById('selectOffice');
var option;
for (var i = 0, len = data.length; i < len; i++) {
    option = doc.createElement('option');
    option.value = data[i].NID;
    option.text = data[i].SNAME;
    element.appendChild(option);
}
selectOffice.appendChild(element);

变量的注意事项

多个变量声明

//多个变量一块声明,比多个单个变量声明要快
var doc = document,
    element = doc.createDocumentFragment(),
    selectOffice = doc.getElementById('selectOffice'),
    option;

对象多次引用 不好的实例

obj.value = obj.value.replace(/[^\d.]/g, "");   //清除“数字”和“.”以外的字符  
obj.value = obj.value.replace(/^\./g, "");      //验证第一个字符是数字而不是.  
obj.value = obj.value.replace(/\.{2,}/g, ".");  //只保留第一个. 清除多余的  
obj.value = obj.value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
obj.value = obj.value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3'); //只能输入两个小数

对象多次引用 好的实例

obj.value = obj.value.replace(/[^\d.]/g, "")         //清除“数字”和“.”以外的字符  
                     .replace(/^\./g, "")            //验证第一个字符是数字而不是.  
                     .replace(/\.{2,}/g, ".")        //只保留第一个. 清除多余的  
                     .replace(".", "$#$")
                     .replace(/\./g, "")
                     .replace("$#$", ".")
                     .replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3'); //只能输入两个小数

循环迭代优化的注意事项

  1. 减值迭代,如果值与顺序无关,可以使用
  2. 简化终止条件,每次循环过程是要计算终止条件的,先确定终止条件
  3. 简化循环体,比如讲循环体内的变量声明, 移出循环外层中
  4. 使用后测试循环

示例

//没优化
for (var i = 0; i < data.length; i++) {
    //代码
}

//确定终止条件和减值迭代
for (var i = data.length - 1; i >= 0; i--) {
    //代码
    //将变量的声明放到,循环外
}

//后测试循环
var i = data.length - 1;
if (i>-1) {
    do {
        //代码
    } while (--i>0)
}
秋风 2016-05-21