编程风格
1:换行
一行长度达到单行的最大字符(80字符)限制时,需要手动换行,通常会在运算符后换行,下一行增加俩个层级的缩进。
例子:
callAfuntion(document,element,window,"some all thing",true,123,
navigator) // 正确
最后一个字符为运算符“,”
2:命名
函数变量采用驼峰式命名 大驼峰:PassCalss 小驼峰 passCalss
变量应为名词 函数应为动词(isXXX canXXX hasXXX getXXX setXXXX)
常量:值初始化之后不再变 大写字符_XXXX (MAX_count)
构造函数:大驼峰式
funtion Person(name){
this.name = name;
}
Person.prototpye.sayname = function(){
return this.name;
}
var me = new Person("SSSS");
3:null
适用场景:
用来初始化可能被赋值成对象的变量
用来和一个已经初始化变量比较,变量可以是也可以不是对象
当函数的参数期望是对象时,用作参数传入
当函数的返回值期望是对象时,用作返回值传出
var person = null;
function getPerson (){
if(condition){
return new Person("SSS");
}else{
return null;
}
}
var person = getPerson();
if(person !== null){
dosomething();
}
不适用场景:
检测是否传入了某参数
检测未初始化的变量
function(arg1,arg2,arg3,arg4){
if(arg4 !==null){
doSomethiing();
}
}
var person;
if(person !== null){
dosomething();
}
null当做对象的占位符最好
4:undefined
null == undefined ===>true
但是 用途是完全不一样的 undefined 是那些未被初始化变量的初始值
5:for in
用来遍历对象属性 遍历自身的还会遍历从原型继承的属性 避免此情况出现 用 hasOwnProperty判断
for(var i in obj){
if(obj.hasOwnProperty(i)){
}
}
6:变量提升 提升到包含这段逻辑函数的顶部执行
function doSomething(){
var result = 10 + value;
var value = 10;
return result; // 结果返回 NaN
}
原因js解析成
function doSomething(){
var result;
var value;
result = 10 + value;
value = 10;
return result; // 结果返回 NaN
}
同理 函数也是一样的会提升
7:严格模式 “use strict”
(function(){})(); 立即执行
8:原始包装类型
String Boolean Number 表示全局作用的一个构造函数 作用:让原始值具有对象般的行为
var name ="SSS";
console.log(name.toUpperCase());
编程实践
1:不要紧耦合 目标松耦合
紧耦合就例如 修改.error的css 的名字 还要改html的
松耦合 修改一个组件 而不需要更改其他组件
2:将css从JavaScript抽离
样式修改时用添加删除类名
将html 从JavaScript抽离
模板放置在服务器
简单模板放置在客户端
使用带自定义type属性的script元素
<script type="text/x-my-template" id="list-item">
<li><a href="%s">%s</a></li>
</script>
// var script = document.getElementById("list-item");
// templateText = script.text;
function addItem (url,text){
var list = document.getElementById("mylist"),
script = document.getElementById("list-item"),
templateText = script.text,
result = sprintf(template,url,text),
div = document.createElement("div");
div.innerHTML = result.replace(/^\s*/,"");
list.appendChild(div.firstChild);
}
addItem("/item/4","fffffff");
如果有问题,也许是模板文本的前导空格导致的
复杂客户端模板 handlebars.js
3:全局变量
尽量避免声明全局的,或使用单全局变量方式
如:
var Dd = {};
Dd.Book = function(title){
this.title = title;
this.page =1;
}
Dd.Book.prototype.topage = funciton(dir){
this.page+=dir;
}
Dd.cha1 = new Dd.Book("ddd");
Dd.cha2 = new Dd.Book("ddsssd");
Dd.cha3 = new Dd.Book("ddxxd");
命名空间:简单通过全局对象的单一属性表示的功能性分组
基于单全局变量的扩充方法 使用模块 YUI模块 AMD模块(异步模块)
4:事件处理
规则:
隔离应用逻辑 (单一函数调用)
var Dd = {
aa:funciton(e){
this.cc(e);
},
cc:funciton(e){
var p = document.getElementById("p");
p.style.left = e.clientX +‘px‘;
p.style.top = e.clientY +‘px‘;
}
}
addListener(element,"click",funciton(e){
Dd.aa(e);
})
e对象被无节制分发了 错误 不过这样是第一步
不要分发事件对象
应用逻辑不应当依赖event对象正确完成功能原因:
方法接口需表明哪些数据是必要的
var Dd = {
aa:funciton(e){
this.cc(e.clientX,e.clientY);
},
cc:funciton(x,y){
var p = document.getElementById("p");
p.style.left = x +‘px‘;
p.style.top = y +‘px‘;
}
}
addListener(element,"click",funciton(e){
Dd.aa(e);
})
5:typeof 检测原始值
原始值: 字符串 数字 布尔值 null undefined
返回: string number boolean object/null undefined(未定义的变量,值为undefined的变量)
不建议用null判断,除非期望返回的是null
typeof name
可用于引用类型Function 返回 function
引用值(除原始值以外的值)
Object Array Date Error typeof 返回均object
检测引用值 instanceof(可检测原型链,自定义类型)
value instanceof Date
function Aa(name){
this.name = name;
}
var me = new Aa("dd");
me instanceof Aa ----> true
检测类型 优雅方案
Object.prototype.toString.call(value) === "[object Array]";(自定义对象不用)
属性(是否存在 in)次选 hasOwnProperty()
6: 配置数据(hardcoded)应用中写死的 如:
URL
需要展示给用户看的字符串
重复值
设置(配置项)
任何可能发现变更的值
function aa(val){
alert(val); //val 配置数据
location.href = "/e/e/e"; //url 配置数据
removeClass(element,"class"); //class配置数据
}
抽离配置数据
var config ={
VAL:"value",
URL:" /e/e/e ",
CSS_CLASS:"class"
};
function aa(val){
alert( config.VAL);
location.href = config.URL;
removeClass(element, config.CSS_CLASS);
}
配置数据保存
1:jSON格式
{“ss”:"dd", “ss”:"dd", “ss”:"dd", “ss”:"dd"}
2:JSONP格式
myfunc( {“ss”:"dd", “ss”:"dd", “ss”:"dd", “ss”:"dd"} )
3:纯JavaScript格式
var config = {“ss”:"dd", “ss”:"dd", “ss”:"dd", “ss”:"dd"}
7:致力于抛出自定义错误(更加容易的调试,库的开发适用)
function getDivs(element){
if(element && element.getElementByTagName){
return element.getElementByTagName("div");
}else{
throw new Error("getDivs(): Argument must be a DOM element")
}
}
执行错误可明确知道问题在哪
捕获错误
try{
something();
}catch(ex){
handleError(ex);
}
8:错误类型
Error 基础类型
EvalError 通过eval()函数执行抛出的
RangeError 数字超出边界
ReferenceError 期望对象不存在
SyntaxError eval()函数有语法错误
TypeError 变量不是期望的类型
URIError encodeURI() encodeURIComponent() decodeURI() decodeURIComponent()等传递非法的URI字符串