编写可维护的JavaScript--读书笔记

缩进层级

1.一个制表符(设置为4个空格,强制)

语句结尾

1.都要加分号(强制)

行的长度
  1. 一行的长度限定在80个字符
如何空行
  1. 在方法之间
  2. 在方法中的局部变量和第一条语句之间
  3. 在多行或者单行注释之前
  4. 在方法内的逻辑片段之间插入空行,提高可阅读性
命名

1.变量和函数 —驼峰式,变量前缀是名词,函数和方法前缀应该是动词,常见的动词 can has is get set

2.常量 —全部大写

3.构造函数 —首字母大写

对象直接量、数组直接量
  1. 直接用对象直接量,然后添加属性。取代先显式地创建Object的实例。数组也是直接建
for-in循环

1.for-in循环都必须使用hasOwnProperty()

函数变量提升
  1. 因为函数变量提升,所以建议总是将局部变量的定义作为函数内的第一条语句,推荐合并var 语句,那些没有初始值的变量来说,它们应当出现在var的尾部
1
2
3
4
var value = 10,
result = value + 10,
i,
len;
  1. 和变量声明一样,函数声明也会被javascript引擎提前,推荐先声明javascript函数然后使用函数
严格模式
  1. 不推荐在全局作用域下使用”use strict”,假如几个文件合并成一个文件会污染了其他文件
相等
  1. 发生强制类型转换的场景一般是判断相等运算符==和!= console.log(5 == “5”);//true,我们规定使用 ‘===’和’!==’
零全局变量
  1. 实现的方法就是使用一个立即执行的函数调用并将所有脚本放置其中,使用的场景是这段不提供任何接口的单会被单独立插到一个页面中,独立开来,也不污染
1
2
3
4
5
6
7
8
9
10
11
//js原生
(function(win) {
var doc = win.document;
//在这里定义其他变量
//其他相关代码
})(window);
//jq
$(function(){
//在这里定义其他变量
//其他相关代码
});
命名空间
  1. 在javascript中可以轻而易举地创造自己的命名空间,每个文件都需要给一个命名空间挂载东西,处理全局污染的代码一般这样子写,这样子保证最少的全局变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var YouGlobal = {
namespace: function(ns) {
var parts =ns.split("."),
object = this,
i,
len;
console.log(this);
for(i = 0,len = parts.length; i< len; i++){
if(!object[parts[i]]){
object[parts[i]] = {};
}
object = object[parts[i]];
}

return object;
}
}

//使用
YouGlobal.namespace("Books.MaintainableJavaScript");
事件处理
  1. 应用逻辑和所有事件处理程序中需要抽离出来,好的做法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var MyApplication = {
handleClick: function(event) {

//假设事件支持DOM LEVEL2
event.preventDefault();
event.stopPropagation();

//传入应用逻辑
this.showPopup(event.clientX, event.clientY);
}
showPopup: function(x, y) {
var popup = document.getElementById("popup");
popup.style.left = x + "px";
popup.style.top = y + "px";
popup.className = "releal";
}
};

addListener(element, "click", function(event) {
MyApplication.handleClick(event);
});

避免空比较

检测原始值
  1. 如果你希望一个值是字符床、数字、布尔值或者undefined,最佳选择是使用typeof运算符会发挥一个表示值的类型的字符串 推荐无符号运算符的写法
1
2
3
typeof name === "string"
//编程时要杜绝使用typeof来检测null的类型因为
console.log(typeof null); //"object"
  1. 如果你需要检测null,则直接使用恒等运算符(===)或者非恒等运算符(!==)
  2. 检测函数最好的方法是typeof
1
typeof function(){} //"function"
  1. 判断数组
1
Array.isArray([1,2]) //true
  1. 检测实例对象的某个属性是否存在
1
2
if("related" in object){}
if(object.hasOwnProperty("related")){}

将配置数据从代码中分离出来

抽离配置数据
  1. 尽量的把一些配置写到config上,不要掺杂在javascript代码中

抛出错误

try-catch
1
2
3
4
5
6
try {
somethingThatMightCauseAnError();//比如进行读文件的操作
}catch(ex) {
//千万不要将try-catch中的catch留空,应该写点什么来处理错误

}
浏览器嗅探
  1. User-Agent 检测浏览器并不总是提供它们原始的user-agent字符串几乎所有得浏览器都可以使用现成的工具来修改用户代理。开发者往往会担心这一点会导致用户代理检测失效,现成的工具来修改用户代理。
  2. 特性检测 使用特性检测是正确和恰当的,因为代码对特性做检测,当特性存在时才使用,首先检测document.getElementById等。
  3. 如果你想使用用户代理嗅探,记住者一点:这么在做唯一安全的方式是针对旧的或者特定版本的浏览器,而绝不应当针对最新版本或者未来的浏览器。尽量的使用特性检测。
继承
  1. 基于对象继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var person = {
name: "huangqin",
sayname: function() {
alert(this.name);
}
};
var myPerson = Object.create(person);
myPerson.sayName();//弹出“huangqin”
myPerson.sayName = function() {
alert("liuyongle");
}
myPerson.sayName();//弹出“liuyongle”
person.sayName();//弹出“huangqin”
//重新定义myPerson.sayName()会自动切断对person.sayName()的访问
  1. 基于类的继承
1
2
3
4
5
6
//基于类的继承是从一个已知的对象继承,这里的继承是依赖于原型的,因此,基于类的继//承的通过构造函数实现的,而非对象。这意味着,需要访问被继承对象的构造函数。

function MyError(message) {
this.message = message;
}
MyError.prototype = new Error();

自动化

1.略,看一下之前我写的前端自动化构建工具

文件和目录结构

  1. 建一个项目工程的步骤:建好文件和目录结构、文件的构建、验证、合并、加工,文件的精简和压缩
  2. 文件精简的工具: http://github.com/jayli/TPacker

    服务器端的控制
  3. 现在浏览器都支持HTTP压缩并且都会发送一个HTTP头作为请求的一部分 ,指明压缩类型,例如 Accet-Encoding:gzip, deflate .

  4. apache 2 和nginx是最受欢迎的WEB服务器之二,都对gzip作为http压缩。

文档化

1.选择markdown风格的文档编辑

自动化测试

  1. 编制打包计划
  2. 开发版本的构建
  3. 集成版本的构建
  4. 发布版本的构建

组装在一起

  1. jenkins CI系统 持续集成是频繁、持续地在多个团短成员的工作中进行集成,并且给予反馈