Skip to content

Commit 424046e

Browse files
committed
代码重构原则
1 parent fbb36a4 commit 424046e

File tree

1 file changed

+369
-0
lines changed

1 file changed

+369
-0
lines changed

twenty-one-chapter/index.js

+369
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
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

Comments
 (0)