|
| 1 | +//代码重构 |
| 2 | + |
| 3 | +//提炼函数 |
| 4 | +//1. 避免出现超大函数 |
| 5 | +//2. 独立出来函数有助于代码复用 |
| 6 | +//3. 独立出来的函数更容易被复写 |
| 7 | +//4. 独立出来的函数如果拥有一个良好的命名,它本身起到了注释的作用 |
| 8 | + |
| 9 | +var getUserInfo = function () { |
| 10 | + ajax('xxx.com/userinfo',function(data){ |
| 11 | + console.log('userId',data.userId); |
| 12 | + console.log('username',data.username); |
| 13 | + console.log('nickname',data.nickname); |
| 14 | + }) |
| 15 | +} |
| 16 | + |
| 17 | +//改成 |
| 18 | +var getUserInfo = function(){ |
| 19 | + ajax('xxx.com/userinfo',function(data){ |
| 20 | + printDetails(data); |
| 21 | + }) |
| 22 | +} |
| 23 | + |
| 24 | +var printDetails = function(data){ |
| 25 | + console.log('userId',data.userId); |
| 26 | + console.log('username',data.username); |
| 27 | + console.log('nickname',data.nickname); |
| 28 | +} |
| 29 | + |
| 30 | +//合并重复的条件片段 |
| 31 | +var paging = function(currPage){ |
| 32 | + if(currPage <= 0){ |
| 33 | + currPage = 0; |
| 34 | + jump(currPage); |
| 35 | + }else if (currPage >= totalPage){ |
| 36 | + currPage = totalPage; |
| 37 | + jump(currPage); |
| 38 | + }else { |
| 39 | + jump(currPage); |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +//改成 |
| 44 | +var paging = function(currPage){ |
| 45 | + if(currPage <= 0){ |
| 46 | + currPage = 0; |
| 47 | + }else if(currPage >= totalPage){ |
| 48 | + currPage = totalPage; |
| 49 | + } |
| 50 | + jump(currPage); |
| 51 | +} |
| 52 | + |
| 53 | +// 把条件分支语句提炼成函数 |
| 54 | +var getPrice = function(price){ |
| 55 | + var date = new Date(); |
| 56 | + if(date.getMonth() >= 5 && date.getMonth() <= 8){ //夏天 |
| 57 | + return price * 0.8; |
| 58 | + } |
| 59 | + return price; |
| 60 | +} |
| 61 | + |
| 62 | +//改写 |
| 63 | +var isSummer = function(){ |
| 64 | + var date = new Date(); |
| 65 | + return date.getMonth() >= 5 && date.getMonth() <= 8; |
| 66 | +} |
| 67 | + |
| 68 | +var getPrice = function(price){ |
| 69 | + if(isSummer()){ |
| 70 | + return price * 0.8; |
| 71 | + } |
| 72 | + return price; |
| 73 | +} |
| 74 | + |
| 75 | + |
| 76 | +//合理使用循环 |
| 77 | +//ie9 以下的ie 浏览器 |
| 78 | +var createXHR = function(){ |
| 79 | + var xhr; |
| 80 | + try { |
| 81 | + xhr = new ActiveXObject('MSXML2.XMLHttp.6.0'); |
| 82 | + }catch(e){ |
| 83 | + try{ |
| 84 | + xhr = new ActiveXObject('MSXML2.XMLHttp.3.0') |
| 85 | + }catch(e){ |
| 86 | + xhr = new ActiveXObject('MSXML2.XMLHttp') |
| 87 | + } |
| 88 | + } |
| 89 | + return xhr; |
| 90 | +} |
| 91 | + |
| 92 | +var xhr = createXHR(); |
| 93 | + |
| 94 | +//改写成 |
| 95 | +var createXHR = function(){}; |
| 96 | +var versions = ['MSXML2.XMLHttp.6.0','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp']; |
| 97 | +for(var i=0,version;version = versions[i++];){ |
| 98 | + try{ |
| 99 | + return new ActiveXObject(version); |
| 100 | + }catch(e){ |
| 101 | + |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +// 提前让函数退出代替嵌套条件分支 |
| 106 | +var del = function(obj){ |
| 107 | + var ret; |
| 108 | + if(!obj.isReadOnly){ |
| 109 | + if(obj.isFolder){ |
| 110 | + ret = deleteFolder(obj); |
| 111 | + }else if (obj.isFile){ |
| 112 | + ret = deleteFile(obj); |
| 113 | + } |
| 114 | + } |
| 115 | + return ret; |
| 116 | +} |
| 117 | + |
| 118 | +//改写成 |
| 119 | +var del = function(obj){ |
| 120 | + if(obj.isReadOnly){// 反转 if 表达式 |
| 121 | + return; |
| 122 | + } |
| 123 | + if(obj.isFolder){ |
| 124 | + return deleteFolder(obj); |
| 125 | + } |
| 126 | + if(obj.isFile){ |
| 127 | + return deleteFile(obj); |
| 128 | + } |
| 129 | +} |
| 130 | + |
| 131 | + |
| 132 | +// 传递对象参数代替过长的参数列表 |
| 133 | +var setUserInfo = function(id,name,address,sex,mobile,qq){ |
| 134 | + console.log('id',id); |
| 135 | + console.log('name',name); |
| 136 | + console.log('address',address); |
| 137 | + console.log('sex',sex); |
| 138 | + console.log('mobile',mobile); |
| 139 | + console.log('qq',qq); |
| 140 | +} |
| 141 | + |
| 142 | +setUserInfo(001,'seve','hefei','male','182********',88990011); |
| 143 | + |
| 144 | +//改写成 |
| 145 | +var setUserInfo = function(obj){ |
| 146 | + console.log('id',obj.id); |
| 147 | + console.log('name',obj.name); |
| 148 | + console.log('address',obj.address); |
| 149 | + console.log('sex',obj.sex); |
| 150 | + console.log('mobile',obj.mobile); |
| 151 | + console.log('qq',obj.qq); |
| 152 | +} |
| 153 | + |
| 154 | +setUserInfo({ |
| 155 | + id:1234, |
| 156 | + name;'seve', |
| 157 | + address:'hefei', |
| 158 | + sex:'male', |
| 159 | + mobile:'137**********', |
| 160 | + qq:88990011 |
| 161 | +}) |
| 162 | + |
| 163 | +//尽量减少参数数量 |
| 164 | +var draw = function(width,height,square){} |
| 165 | + |
| 166 | +//改成 |
| 167 | +var draw = function(width,height){ |
| 168 | + var square = width * height ; |
| 169 | +} |
| 170 | + |
| 171 | +//少用三目运算符,提高代码的可读性 |
| 172 | +var global = typeof window !== 'undefined' ? window:this; |
| 173 | + |
| 174 | +if(!aup || !bup){ //可读性太差,bad |
| 175 | + return a === doc ? -1 : |
| 176 | + b === doc ? 1: |
| 177 | + aup ? -1: |
| 178 | + bup ? 1: |
| 179 | + sortInput ? |
| 180 | + (indexOf.call(sortInput,a) - indexOf.call(sortInput,b)): |
| 181 | + 0; |
| 182 | +} |
| 183 | + |
| 184 | +//合理的使用链式调用 |
| 185 | +//缺点,调试困难 |
| 186 | +var User = function(){ |
| 187 | + this.id = null; |
| 188 | + this.name = null; |
| 189 | +} |
| 190 | + |
| 191 | +User.prototype.setId = function(id){ |
| 192 | + this.id = id; |
| 193 | + return this; |
| 194 | +}; |
| 195 | + |
| 196 | +User.prototype.setName = function(name){ |
| 197 | + this.name = name; |
| 198 | + return this; |
| 199 | +}; |
| 200 | +console.log(new User().setId(1234).setName('even')); |
| 201 | + |
| 202 | +//或者 |
| 203 | +var User = { |
| 204 | + id:null, |
| 205 | + name:null, |
| 206 | + setId:function(id){ |
| 207 | + this.id = id; |
| 208 | + return this; |
| 209 | + }, |
| 210 | + setName:function(name){ |
| 211 | + this.name = name; |
| 212 | + return this; |
| 213 | + } |
| 214 | +} |
| 215 | +console.log(User().setId(1234).setName('even')); |
| 216 | + |
| 217 | +//分解大型类 |
| 218 | +var Spirit = function(name){ |
| 219 | + this.name = name; |
| 220 | +} |
| 221 | + |
| 222 | +Spirit.prototype.attack = function(type){ |
| 223 | + if(type === 'waveBoxing'){ |
| 224 | + console.log(this.name+': 使用波动拳'); |
| 225 | + }else if(type === 'whirlKick'){ |
| 226 | + console.log(this.name+': 使用旋风腿'); |
| 227 | + } |
| 228 | +} |
| 229 | + |
| 230 | +var spirit = new Spirit('RYU'); |
| 231 | + |
| 232 | +spirit.attack('waveBoxing'); |
| 233 | +spirit.attack('whirlKick'); |
| 234 | + |
| 235 | +//分解成更小的类,把攻击方式委托给Attack类 |
| 236 | +var Attack = function(spirit){ |
| 237 | + this.spirit = spirit; |
| 238 | +} |
| 239 | + |
| 240 | +Attack.prototype.start = function(type){ |
| 241 | + return this.list[type].call(this); |
| 242 | +}; |
| 243 | + |
| 244 | +Attack.prototype.list = { |
| 245 | + waveBoxing:function(){ |
| 246 | + console.log(this.spirit.name+': 使用波动拳'); |
| 247 | + }, |
| 248 | + whileKick:function(){ |
| 249 | + console.log(this.spirit.name+': 使用旋风腿'); |
| 250 | + } |
| 251 | +} |
| 252 | + |
| 253 | +var Spirit = function(name){ |
| 254 | + this.name = name; |
| 255 | + this.attackObj = new Attack(this); |
| 256 | +} |
| 257 | + |
| 258 | +Spirit.prototype.attack = function(type){ |
| 259 | + this.attackObj.start(type); |
| 260 | +} |
| 261 | + |
| 262 | +var spirit = new Spirit('RYU'); |
| 263 | + |
| 264 | +spirit.attack('waveBoxing'); |
| 265 | +spirit.attack('whirlKick'); |
| 266 | + |
| 267 | +//用 return 推出多重循环 |
| 268 | +// 要在内层循环中判断,当达到某个临界条件时 |
| 269 | +// 退出外层的循环。我们大多数时候会引入一个控制标记变量 |
| 270 | +var func = function(){ |
| 271 | + var flag = false; |
| 272 | + for(var i=0;i<10;i++){ |
| 273 | + for(var j=0;j<10;j++){ |
| 274 | + if(i*j > 30){ |
| 275 | + flag = true; |
| 276 | + break; |
| 277 | + } |
| 278 | + } |
| 279 | + if(flag === true){ |
| 280 | + break; |
| 281 | + } |
| 282 | + } |
| 283 | +} |
| 284 | +//第二种方法设置循环标记 |
| 285 | +var func = function(){ |
| 286 | + outerloop; |
| 287 | + for(var i=0;i<10;i++){ |
| 288 | + innerloop; |
| 289 | + for(var j=0;j<10;j++){ |
| 290 | + if(i*j > 30){ |
| 291 | + break outerloop; |
| 292 | + } |
| 293 | + } |
| 294 | + } |
| 295 | +} |
| 296 | + |
| 297 | +// 需要中止循环的时候直接退出整个方法 |
| 298 | +var func = function(){ |
| 299 | + for(var i=0;i<10;i++){ |
| 300 | + for(var j=0;j<10;j++){ |
| 301 | + if(i*j > 30){ |
| 302 | + return; |
| 303 | + } |
| 304 | + } |
| 305 | + } |
| 306 | +} |
| 307 | + |
| 308 | +// 循环之后还有一些将被执行的代码? |
| 309 | +var func = function(){ |
| 310 | + for(var i=0;i<10;i++){ |
| 311 | + for(var j=0;j<10;j++){ |
| 312 | + if(i *j > 30){ |
| 313 | + return; |
| 314 | + } |
| 315 | + } |
| 316 | + } |
| 317 | + console.log(1)//没有被执行 |
| 318 | +} |
| 319 | + |
| 320 | +// 为了解决这个问题,我们可以把循环后面的代码放到 return 后面,如果代码比较多,就应 |
| 321 | +// 该把它们提炼成一个单独的函数 |
| 322 | + |
| 323 | +var print = function(i){ |
| 324 | + console.log(i); |
| 325 | +} |
| 326 | + |
| 327 | +var func = function(){ |
| 328 | + for(var i=0;i<10;i++){ |
| 329 | + for(var j=0;j<10;j++){ |
| 330 | + if(i *j > 30){ |
| 331 | + return print(i); |
| 332 | + } |
| 333 | + } |
| 334 | + } |
| 335 | +} |
| 336 | + |
| 337 | +func(); |
| 338 | + |
| 339 | + |
| 340 | + |
| 341 | + |
| 342 | + |
| 343 | + |
| 344 | + |
| 345 | + |
| 346 | + |
| 347 | + |
| 348 | + |
| 349 | + |
| 350 | + |
| 351 | + |
| 352 | + |
| 353 | + |
| 354 | + |
| 355 | + |
| 356 | + |
| 357 | + |
| 358 | + |
| 359 | + |
| 360 | + |
| 361 | + |
| 362 | + |
| 363 | + |
| 364 | + |
| 365 | + |
| 366 | + |
| 367 | + |
| 368 | + |
| 369 | + |
0 commit comments