面向对象的选项卡

将面向过程的选项卡改写成面向对象的形式

面向过程的选项卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.onload = function(){
var aBtn = document.getElementsByTagName('button');
var aDiv = document.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++){
aBtn[i].index=i;
aBtn[i].onclick=function(){
for(var j=0;j<aBtn.length;j++){
aBtn[j].className='';
aDiv[j].style.display='none';
}
this.className='active';
aDiv[this.index].style.display='block';
}
}
}

改写成面向对象

  1. 将嵌套的函数挪到外部,变成构造函数prototype上的方法
  2. 最大的那个函数变成构造函数
  3. 将变量变成属性,函数变成方法
  4. 所有属性和prototype上的方法前面添加this
  5. 调整this的指向
  6. 使用new运行这个构造函数

函数不能有嵌套,将嵌套的函数提到外面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
window.onload = function(){
var aBtn = document.getElementsByTagName('button');
var aDiv = document.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++){
aBtn[i].index=i;
aBtn[i].onclick = fnTab;
}
}
function fnTab(){
for(var j=0;j<aBtn.length;j++){
aBtn[j].className=''; //此处无法获取aBtn,因为aBtn声明在onload的内部
aDiv[j].style.display='none';//此处无法获取aDiv,因为aDiv声明在onload的内部
}
this.className='active';
aDiv[this.index].style.display='block';
}

共用的变量要在外部先声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//将共用的变量声明在全局
var aBtn = null;
var aDiv = null;
window.onload = function(){
aBtn = document.getElementsByTagName('button');
aDiv = document.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++){
aBtn[i].index=i;
aBtn[i].onclick = fnTab;
}
}
function fnTab(){
for(var j=0;j<aBtn.length;j++){
aBtn[j].className='';
aDiv[j].style.display='none';
}
this.className='active';
aDiv[this.index].style.display='block';
}

将总集合的函数变成构造函数

  1. 变成构造函数
  2. 变量 -> 属性(所有变量名前面加上this)
  3. 函数 -> 方法(将函数放到构造函数的prototype上)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//变成构造函数
function TabSwitch(){
//将变量变成属性
this.aBtn = document.getElementsByTagName('button');
this.aDiv = document.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++){
this.aBtn[i].index=i;
this.aBtn[i].onclick = this.fnTab;
}
}
//函数变成构造函数prototype上的方法
TabSwitch.prototype.fnTab = function(){
for(var j=0;j<this.aBtn.length;j++){
this.aBtn[j].className='';
this.aDiv[j].style.display='none';
}
this.className='active';
this.aDiv[this.index].style.display='block';
}

调整this的指向

修改this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
new TabSwitch();
function TabSwitch(){
var _this = this; //_this === TabSwitch
//将变量变成属性
this.aBtn = document.getElementsByTagName('button');
this.aDiv = document.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++){
this.aBtn[i].index=i;
this.aBtn[i].onclick = function (){
//通过闭包,获取函数外部的_this
_this.fnTab(); //此处的this指向aBtn[i],而我要调用的是构造函数上的fnTab方法,所以要用_this
};
}
}
//函数变成构造函数prototype上的方法
TabSwitch.prototype.fnTab = function(){
for(var j=0;j<this.aBtn.length;j++){
this.aBtn[j].className='';
this.aDiv[j].style.display='none';
}
this.className='active';
this.aDiv[this.index].style.display='block';
}


将构造函数内的this传给方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
new TabSwitch();
function TabSwitch(){
var _this = this; //_this === TabSwitch
//将变量变成属性
this.aBtn = document.getElementsByTagName('button');
this.aDiv = document.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++){
this.aBtn[i].index=i;
this.aBtn[i].onclick = function (){
_this.fnTab(this); //this指向aBtn[i],将这个this传给方法fnTab
};
}
}
//函数变成构造函数prototype上的方法
TabSwitch.prototype.fnTab = function(oBtn){//接收传过来的aBtn[i]
for(var j=0;j<this.aBtn.length;j++){
this.aBtn[j].className='';
this.aDiv[j].style.display='none';
}
oBtn.className='active';
this.aDiv[oBtn.index].style.display='block';
}

最终代码

-------------本文结束感谢您的阅读-------------