JavaScript高级程序设计(第3版)学习笔记 第24章

第24章 最佳实践

1.可维护的代码有以下特征::

  • 可理解性——其他人可以接手代码并理解它的意图和一般途径,而无需原开发人员的完整解释。 
  • 直观性——代码中的东西一看就能明白,不管其操作过程多么复杂。
  • 可适应性——代码以一种数据上的变化不要求完全重写的方法撰写。
  • 可扩展性——在代码架构上已考虑到在未来允许对核心功能进行扩展。
  • 可调试性——当有地方出错时,代码可以给予你足够的信息来尽可能直接地确定问题所在。

2.JavaScript 代码的书写约定

(1)可读性:与代码作为文本文件的格式化方式有关,常见的缩进大小为 4 个空格,并对以下地方进行注释:

  • 函数和方法——每个函数或方法都应该包含一个注释,描述其目的和用于完成任务所可能使用 的算法。陈述事先的假设也非常重要,如参数代表什么,函数是否有返回值(因为这不能从函 数定义中推断出来)。
  • 大段代码——用于完成单个任务的多行代码应该在前面放一个描述任务的注释。
  • 复杂的算法——如果使用了一种独特的方式解决某个问题,则要在注释中解释你是如何做的。 这不仅仅可以帮助其他浏览你代码的人,也能在下次你自己查阅代码的时候帮助理解。
  • Hack——因为存在浏览器差异,JavaScript 代码一般会包含一些 hack。

(2)适当给变量和函数起名字:

  • 变量名应为名词如 car 或 person。
  • 函数名应该以动词开始,如 getName()。返回布尔类型值的函数一般以 is 开头,如isEnable()。
  • 变量和函数都应使用合乎逻辑的名字,不要担心长度。

(3)变量类型透明,防止忘记变量所应包含的数据类型

  • 初始化:当定义了一个变量后,它应该被初始化为一个值,来暗示它将来应该如何应用。
  • 使用匈牙利标记法来指定变量类型,在变量名之前加上一个或多个字符 来表示数据类型。
  • 使用类型注释。类型注释放在变量名右边,但是在初始化前面。

3.由于 JavaScript 必须与 HTML 和 CSS 共存,所以让各自完全定义其自己的目的非常重要:JavaScript 应该定义行为,HTML 应该定义内容,CSS 应该定义外观。

  • 避免在 JavaScript 中创建大量 HTML。
  • 使用JavaScript 用于插入数据时,尽量不要直接插入 标记。一般可以在页面中直接包含并隐藏标记,然后等到整个页面渲染好之后,用 JavaScript 显示该标记,而非生成它。
  • 使用 JavaScript 来更改样式时,通过动态更改样式类而非特定样式来实现(更改类名)。

4.将应用逻辑和事件处理程序相分离,事件处理程序应该从事件对象中提取相关信息,并将这些信息传送到处理应用逻辑的某个方法中。

//业务逻辑
function validateValue(value){
    value = 5 * parseInt(value);
    if (value > 10){
        document.getElementById("error-msg").style.display = "block"; 
    }
}

//事件处理程序
function handleKeyPress(event){
    event = EventUtil.getEvent(event);
    if (event.keyCode == 13){
        var target = EventUtil.getTarget(event);
        validateValue(target.value);
    }
}

5.编程实践:

  • 尊重对象所有权:不能修改不属于你的对象
  • 避免全局量
  • 避免与 null 进行比较
  • 使用常量

6.提升性能:

  • 避免全局查找:将在一个函数中会用到多次的全局对象存储为局部变量来使用。
  • //包含了三个对于全局 document 对象的引用。如果在页面上有多个图片,那么引用就会被执行多次甚至上百次
    function updateUI(){
        var imgs = document.getElementsByTagName("img");
        for (var i=0, len=imgs.length; i < len; i++){
            imgs[i].title = document.title + " image " + i;
        }
        var msg = document.getElementById("msg");
        msg.innerHTML = "Update complete.";
    }
    
    //document 对象存在本地的 doc 变量中,现在的函数只有一次全局查找
    function updateUI(){
        var doc = document;
        var imgs = doc.getElementsByTagName("img"); 
        for (var i=0, len=imgs.length; i < len; i++){
            imgs[i].title = doc.title + " image " + i;
        }
        var msg = doc.getElementById("msg");
        msg.innerHTML = "Update complete.";
    }
  • 避免 with 语句:使用局部变量保存而不引入新的作用域。0
  • //由于额外的作用域链查找,在 with 语句中执行的代码 肯定会比外面执行的代码要慢。
    function updateBody(){
        with(document.body){
           alert(tagName);
           innerHTML = "Hello world!";
        }
    }
    
    //使用局部变量达到相同的效果
    function updateBody(){
            var body = document.body
            alert(body.tagName);
            body.innerHTML = "Hello world!";
    }
  • 避免不必要的属性查找:多使用局部变量将属性查找替换为值查找。如果即可以用数字化的数组位置进行访问(O(1)操作),也可以使用命名属性(O(n)操作),那么使用数字位置。
  • //有 6 次属性查找,数代码中的点的数量就可以确定属性查找的次数
    var query = window.location.href.substring(window.location.href.indexOf("?"));
    
    // 4 次属性查找
    var url = window.location.href;
    var query = url.substring(url.indexOf("?"));
  • 优化循环 :
    (1) 减值迭代——大多数循环使用一个从 0 开始、增加到某个特定值的迭代器。在很多情况下,从最大值开始,在循环中不断减值的迭代器更加高效。
    (2) 简化终止条件——由于每次循环过程都会计算终止条件,所以必须保证它尽可能快。也就是说避免属性查找或其他 O(n)的操作。
    (3) 简化循环体——循环体是执行最多的,所以要确保其被最大限度地优化。确保没有某些可以被 很容易移出循环的密集计算。
    (4)使用后测试循环——最常用for循环和while循环都是前测试循环。而如do-while这种后测 18 试循环,可以避免最初终止条件的计算,因此运行更快。
  • for (var i=0; i < values.length; i++){
        process(values[i]);
    }
    //修改
    var i=values.length -1;
    if (i > -1){
        do {
            process(values[i]);
        }while(--i >= 0);
    }
  •  展开循环:当循环的次数是确定的,消除循环并使用多次函数调用往往更快 。
  • 避免双重解释
  • /某些代码求值——避免!! 
    eval("alert('Hello world!')");
    //创建新函数——避免!!
    var sayHi = new Function("alert('Hello world!')");
    //设置超时——避免!! 
    setTimeout("alert('Hello world!')", 500);
    
    //已修正
    alert('Hello world!');
    //创建新函数——已修正
    var sayHi = function(){
            alert('Hello world!');
        };
    //设置一个超时——已修正 
    setTimeout(function(){
            alert('Hello world!');
    }, 500);

 

  • 原生方法较快——只要有可能,使用原生方法而不是自己用 JavaScript 重写一个。原生方法是用 诸如 C/C++之类的编译型语言写出来的,所以要比 JavaScript 的快很多很多。JavaScript 中最容 易被忘记的就是可以在 Math 对象中找到的复杂的数学运算;这些方法要比任何用 JavaScript 写 的同样方法如正弦、余弦快的多。
  • Switch 语句较快 —— 如果有一系列复杂的 if-else 语句,可以转换成单个 switch 语句则可 以得到更快的代码。还可以通过将 case 语句按照最可能的到最不可能的顺序进行组织,来进一 步优化 switch 语句。
  • 位运算符较快 —— 当进行数学运算的时候,位运算操作要比任何布尔运算或者算数运算快。选 择性地用位运算替换算数运算可以极大提升复杂计算的性能。诸如取模,逻辑与和逻辑或都可 以考虑用位运算来替换。
  • 使用一个 var 语句声明多个变量比单个变量分别声明快很多。
  • 当使用迭代值(也就是在不同的位置进行增加或减少的值)的时候,尽可能合并语句。
  • var name = values[i];
        i++;
    
    //组合成一个语句
    var name = values[i++];
  • 使用数组和对象字面量
  • //只用一条语句创建和初始化数组 
    var values = [123, 456, 789];
    //只用一条语句创建和初始化对象 
    var person = {
        name : "Nicholas",
        age : 29,
        sayName : function(){
            alert(this.name);
        }
    };
  • 最小化现场更新:使用文档片段来构建 DOM 结构,然后再将其添加到现存的文档中。
  • 对于大 的 DOM 更改,使用 innerHTML 要比使用标准 DOM 方法创建同样的 DOM 结构快得多。
  • 使用事件代理
  • 最小化访问 HTMLCollection 的次数可以极大地改进脚本的性能。

7.部署:

  • Web 应用中尽可能使用最少的 JavaScript 文件,将这源代码合并为一个或几个归并文件。
  • 运行 JavaScript 验证器来确保没有语法错误或者是代码没有潜在的问题。
  • 使用压缩器将文件尽可能变小。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值