第24章JS之最佳实践

一:可维护性

(1)什么是可维护的代码:

1.可理解性
2.直观性
3.可适应性--代码以一种数据上的变化不要求完全重写的方法撰写
4.可扩展性--在代码架构上已考虑到在未来允许对核心功能进行扩展
5.可调实性

(2) 代码约定

1.可读性--在代码中加入必要的注释进行描述
2.变量和函数命名
3.变量类型透明: 例: var found /* :Boolean */  ---加入注释确保变量类型确定并可见

(3)松散耦合:只要应用的某个部分过分依赖于另一个部分,代码就会耦合过紧,难以维护。

1.解耦HTML/JavaScript
2.解耦css/javascript
3.解耦应用逻辑/事件处理程序:较好的方法是将应用逻辑和事件处理程序相分离,

这样两者分别处理各自的东西。一个事件处理程序应该从事件处理对象中提取相关信息,并将这些信息传送到处理应用逻辑的某个方法中。

(4)编程实践

1.尊重对象所有权
(1)不要为实例或原型添加属性
(2)不要为实例或原型添加方法
(3)不要重定义已存在的方法
2.避免全局变量
可以使用功能性全局命名空间
var wrox = {};
有关name的: wrox.aboutName = {}
有关age的: wrox.aboutAge = {}
虽然命名空间会需要多写一些代码,但是对于可维护的目的而言,是非常值得的。命名空间有助于确保代码可以在同一个页面上与其他代码以无害的方式一起工作。
3.避免与null进行比较
代码中null越少,就越容易确定代码的目的,消除不必要的错误。
4.使用常量
比如:

      function validate(value){
           if( !value ){
                alert("Invalid value!");
                location.href = "/error/invalid.php";
           }
      }  
  可以通过将数据抽取出来变成单独定义的常量的方式,将应用逻辑与数据修改隔离开来
  var Constants = {
      INVALID_VALUE_MSG: 'Invalid value!',
      INVALID_VALUE_URL: '/error/invalid.php'
  }
  function validate(value){
       if( !value ){
            alert(Constants['INVALID_VALUE_MSG'] );
            location.href =Constants['INVALID_VALUE_URL']
       }
  }        
 这些变化可以允许数据在无需接触使用它的函数的情况下进行变更;
  在将数据和他的使用逻辑进行分离时,要注意的值的类型如下所示
  1.重复值:任何在多处重复使用的值都应该抽取成一个常量
  2.用户界面字符串:任何用于显示给用户的字符串,都应该被抽取出来以方便国际化
  3.urls:推荐一个公共地方存放所有url
  4:任意可能被更改的值:如果这个值以后会被更改,那么就应该提取出来作为一个常量;

二:性能

(1)注意作用域:只要能减少花费在做用域上时间,就能增加脚本的整体性能。

  1.避免全局查找
  funtion updateUI(){
              var images = document.getElementsByTagName('img');
              for( var i = 0,len = images.length; i < len; i++){
                   imgs[i].title = document.title + 'images' + i;
              }
              var msg = document.getElementsById('msg');
              msg.innerHtml = "update complete.";
  }
  变化为:
  funtion updateUI(){
              var doc = document;
              var images = doc.getElementsByTagName('img');
              for( var i = 0,len = images.length; i < len; i++){
                   imgs[i].title = doc.title + 'images' + i;
              }
              var msg = doc.getElementsById('msg');
              msg.innerHtml = "update complete.";
  }
  通过将document对象存放在本地的doc变量中,函数中只有一次的全局查找,速度更快。
  将一个函数中会用到多次的全局对象存储为局部变量总是没错的


2.避免with语句
 with语句会创建自己的作用域,因此会增加其中执行的代码的作用域链的长度。

由于额外的作用域链查找,在with语句中执行的代码肯定会比外面执行的代码慢
(2)选择正确的方法
1.避免不必要的属性查找
var value = 5;
var sum = 10 + value;
alert(sum)

以上代码的整体复杂度为O(1),O(1)表示,不管有多少值,需要获取常量值的时间都是一样的,获取常量值是非常高效的过程;
在javascript中,访问数组元素也是一个O(1)操作

换言之,在js中,常量操作和数组操作都是O(1)的算法复杂度;

使用变量和数组要比访问对象上的属性更有效率;后者是一个O(n)操作
对象上任何属性查找都要比访问变量或者数组花费更长时间;
2.优化循环:
3.展开循环
4。避免双重解释
5.性能的其他注意事项
(1)只要有可能,使用原生方法而不是自己用js重新写一个。原生方法都是用诸如C/C++之类的编译型语言写出来的,所以要比js的快很多很多。
(2)switch语句较快:将复杂的if-else转换为switch语句
(3)位运算符较快

(3)最小化语句数:完成多个操作的单个语句要比完成单个操作的多个语句快;
1.多个变量声明:

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

转换为:
//一个语句
var count = 5,
    color = 'blur',
    values = [1,2,3],
    now = new Date();

2.插入迭代值:
var name = values[i];
i++;

转换为:var name = values[i++];

3.使用数组和对象字面量来创造函数和变量;

(4)优化DOM交互:在js中,dom毫无疑问是最慢的一部分。理解如何优化与dom的交互,可以极大提高脚本完成的速度;
1.最小化现场更新
一旦你需要访问的dom部分是已经显示在页面的一部分,那么你就是在进行一个现场更新;

var list = document.getElementById('myList'),
    item,
    i;
for(var i = 0; i < 10; i++ ){
   item = document.createElement('li');
   list.appendChild(item);
   item.appendChild(document.createTextNode("item" + i)));
}

转换为:
var list = document.getElementById('myList'),
    fragment = document.createDocumentFragment(),
    item,
    i;
for( var i = 0; i < 10; i++ ){
   item = document.createElement('li');
   fragment.appendChild(item);
   item.appendChild(document.createTextNode("item" + i)));          
}

避免频繁的dom操作,最好先将所有dom操作存储起来,然后一次性插入到文档结构中;

2.使用innerHTML
推荐大小都使用使用innerHTML来创建dom方法。
var list = document.getElementById('myList'),
    html = '',
    i;
for( var i = 0; i < 10; i++ ){
    html += "<li> item " + i + "</li>";
}
list.innerHTML = html;

3.使用事件代理
页面上的事件处理程序的数量和页面响应用户交互的速度之间有个负相关;为了减轻这种惩罚,最好使用事件代理;

三:部署

1.构建过程:
你的代码应该在编译压缩之后放入浏览器中,理由如下:
(1)知识产权问题:避免别人从有完整注释代码中找到漏洞;
(2)文件大小:
(3)代码组织:组织代码要考虑到可维护性并不一定是传送给浏览器的最好方式;
2.验证
使用自动构建工具来完成代码验证,如webpack;
3.压缩
当谈及js文件压缩,其实是在讨论两个东西,代码长度和配重;
代码长度:浏览器所需解析的字节数
配重:实际从服务器传送到浏览器的字节数
(1)文件压缩
压缩器一般进行如下一些步骤
1.删除额外的空白(包括换行)
2.删除所有注释
3.缩短变量名
(2)HTTP压缩

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容