代码书写与命名规范,参照
airbnb-base
规则,https://wenku.baidu.com/view/710562a47075a417866fb84ae45c3b3567ecddec.html?_wkts_=1708918340625&bdQuery=airbnb-base
nowPageNum
PageController
pageIndex
MAXPAGE
2个
空格方式1 + 1 = 2
;'字符串'
let mod = 1;
let mod2 = 3;
function getList(){};
function getPage(){};
各种类型定义使用,如下:
let num = 1;
let str = 'test';
let array = [];
let json = {};
if else语句使用,if只有一句代码也需要{}
if(条件1 || 条件2){
// 执行1
}
else {
// 执行条件2
}
for语句使用
for(let i = 0,l = list.length;i < l;i += 1){
// 执行语句,list[i]
}
for(let key in jsonObj){
// 执行语句,jsonObj[key]
}
while语句使用
let i = 0;
const l = list.length;
while(i < l){
// 执行语句
i += 1;
// 注意死循环
}
do while语句,尽量避免使用,采用for或者while代替
switch语句使用,当if else达到3个层级以上用swtich
switch(index){
case 1:
// do something
break;
case 2:
// do something
break;
default:break;
}
try catch语句,与if else类似 尽量避免使用continue、with、goto、eval、new Function等业界冷门或者有诟病语句
setTimeout,setInterval方法需要传方法引用,禁止传字符串
计时器时间间隔,需要大于100ms
(做动画除外),小于100ms,用户无法感知,以及耗资源
多元操作符使用
// 容错、赋默认值,注意容错值是否可以false,0,''等值
const event = window.event || e;
// 函数执行
isName && Test();
// 与下面语句意思一样,建议使用以下这种
if(isName){
Test();
}
// 三元操作符
let val = isName ? 'name' : 'error';
// 不建议三元层级关系太多,容易混乱以及可读性差,例如
let val = isName ? 'name' : isChines ? 'china' : 'error';
对于超过1次使用的dom或者bom对象
,需要用变量缓存起来。例如:
const dom = document.getElemntById('test');
dom.style.left = '1px';
dom.style.top = '2px';
回调中包含另外回调(匿名函数),尽量避免,影响可读性,例如:
$.ajax(function(){
$.post(function(){
// do something
});
});
多重循环,尽量避免,例如:
for(var i = 0,l = 10;i < l;i += 1){
for(var j = 0;k = 10;j < k;j += 1){
// do something
}
}
禁止直接用onxxx绑定事件,例如:
document.onkeydown = function(e){
//do something
}
全局情况下,判断变量是否为存在,例如:
//错误的使用
if(foo)return true;
//正确的使用
if(window.foo)return true;
if(typeof foo !== 'undefined')return true;
文件名与文件内的模块名保持一致,字母全小写,用-分割,例如:mod-index.js
同页面或者同大模块的文件,放在一个独立文件夹中,例如:
index文件夹
|--mod-index.js
|--db-index.js
css文件放head中,js文件放body底部,除非需要延迟加载
<head>
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
/**body内容代码*/
<script type="text/javascript" src="js/index.js"></script>
</body>
尽量避免内嵌css、js代码在html页面中 html标签中,class与id,都需要带上js_前缀,表示这个是提供给js用,并没有任何样式上的关联
<div class="head js_head"></div>
<div id="js_head"></div>
JS性能优化原则
- 减少改变dom结构的次数
- 减少选择器的层数,尽量使用id,或带id的选择器,如使用
$('#ul_test li')
而不要使用$('.ul_test li')
- 注意内存回收,特别是将dom节点或dom节点绑定的方法赋值给某个变量,要注意内容回收
- 使用面向对象开发模式,减少变量污染
- 减少绑定方法的次数
- 资源文件载入最小化,如选择合适的图片格式,减少图片大小,对js及css进行压缩等。
//错误的写法
for(let i = 0; i < m.length; i += 1){
}
//正确的写法
for(var i=0,len=m.length; i<len; i += 1){
}
一次性修改dom结构
,避免每次修改dom结构时浏览器对整个dom结构进行重新解析,从而影响性能 //错误的写法
for(let i = 0, len = m.length; i < len; i++){
$('#aaa').append('<p>123123</p>');
}
//正确的写法
var html='';
for(var i = 0,len = m.length; i < len; i++){
html+='<p>123123</p>';
}
$('#aaa').append(html);
``````
使用on()或delegate()代替bind()来为节点绑定方法
使用bind绑定方法经常会面临几个常见问题:
- 当dom节点发生变化时,绑定事件失效,
- 每次修改dom节点都要重新绑定事件
- 使用ajax之类添加的节点,只能在ajax回调之后绑定,当重复调用ajax时会面对上一个问题
使用on()或delegate()的实现事件代理 使用 delegate()和on()方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素),当元素节点发生变化时无需重新绑定
$(document).on('click','#ul_list li',function(e){
});
$('#test').delegate('li','click',,function(e){
});
在开发过程中尽量使用面向对象开发模式
- 单例模示:对各个子功能进行模块封装,实现模块化开发,减少全局变量的使用,方便代码管理及模块修改,使用闭包灵活改变公有或私有变量的生命周期。
- 类:对可重用插件进行封装,方便拓展及重用;
单例结构示例:
var Artical=function(window,document){
var _articalData,
_totalPages=1,//私有全局变量
_curPages=1,
var init=function(param){//私有函数,使用这种方法定义函数需要保证其本身被调用时必须在此函数声明之后
_nextHost="";
_totalPages=1;
_curPage=1;
getPage();
addEvent();
}
function getPage(){//私有函数
if(_articalData){
formatArtical(_articalData);
}
else{
var localparam=location.href.split("/");
var urllink=unescape(localparam[localparam.length-1].split("-")[1]);
$.ajax({
url:_webHost+urllink,
dataType:"html",
type:"get",
success:function(data){
formatArtical($(data));
}
})
}
}
function getMore(nextUrl){
}
var addEvent=function(){
}
var remove=function(){
_articalData=null;
}
var exports = {//开放给外部调用的函数
init : init,
remove:remove,
setData:function(data){//提供给外部修改内部变量的方法
_articalData=data;
}
};
return exports;
}(window,document,undefined);
//调用示例
Artical.init();//调用初始化函数
Artical.setData("111");//修改内部变量_articalData
类结构示例(采用单例和原型链结合),减少实例化时使用new 实例化对象
var Mobile = function(){ //定义单例
var _styleLink=null;//所有对象实例公有参数
var setParam=function(options){//所有对象实例公有函数
}
var _class = function(options){//内部类
var classParam="test";//对象私有变量
this.options=$.extend({
param1:null,
param2:null,
callback:null
},options)
this.init();
}
_class.prototype = {//对象私有方法
init : function(){//对象初始化
this.addEvent();
},
addEvent:function(){//事件绑定
}
}
return {
setting:function(options){//提供给外部调用的方法,修改所有实例的公有参数
setParam(options);
},
create : function(options){//提供给外部调用的方法,创建实例
return new _class(options);
}
}
}();
//调用实例
Mobile.setting({//设置对象所有实例的公有参数
param1:"1111",
param2:"2222"
})
var mb = Mobile.create({//创建实例1
param1:"aaa",
param2:"bbb",
callback:function(){}
});
var mb2= Mobile.create({//创建实例2
param1:"ccc",
param2:"ddd",
callback:function(){}
});
var $li_tags=$("#ul_test li");
for(var i= 0; len = li_tags.length; i < len ;i++){
}
$li_tags.find("a").remove();
var $li_tags=$("#ul_test li");
$li_tags.each(function(index,ele){
//do something.....
});
$li_tags=null;