用面向对象的方法重写选项卡

面向过程的tab选项卡

<!DOCTYPE html>
<html>
<head>
	<title>选项卡--面向对象</title>
	<script type="text/javascript">
        window.onload = function() {
             var oLi = document.getElementsByTagName('li');
             var aDiv = document.getElementsByTagName('div');
             for (var i = 0; i < oLi.length; i++) {
             	oLi[i].index = i;//注意,这里让index等于i是为了点击时切换到相应的div
             	oLi[i].onclick = function() {
                    for (var j = 0; j < oLi.length; j++) {
                    	aDiv[j].style.display = "none";
                    };
                    
                    aDiv[this.index].style.display = "block";
             	}
             };
        }

        
	</script>
	<style type="text/css">
        li {
        	list-style-type: none;
        	display: inline-block;
        	border: 1px solid #000;
        }
        .content{
        	width: 200px;
        	height: 400px;
        	border: 1px solid #000;
        }
	</style>
</head>
<body>
<ul>
	<li>选项1</li>
	<li>选项2</li>
	<li>选项3</li>
</ul>
<div class="content">
	内容1
</div>
<div class="content" style="display:none">
	内容2
</div>
<div class="content" style="display:none">
	内容3
</div>
</body>
</html>

下面我们要把它改成面向对象的选项卡

  • 第一步:解开所有嵌套函数
oLi[i].onclick = function() {...}

将onclick后面的匿名函数提到外面去

...
oLi[i].onclick =tab;
...
function tab() {
                    for (var j = 0; j < oLi.length; j++) {
                    	aDiv[j].style.display = "none";
                    };
                    
                    aDiv[this.index].style.display = "block";
             	}

将几个变量定义到全局,不然tab函数不能使用它

  • 第二步,把window.onload变为“构造函数”
function TabSwich() {
             this.oLi = document.getElementsByTagName('li');
             this.aDiv = document.getElementsByTagName('div');
             for (var i = 0; i < this.oLi.length; i++) {
             	this.oLi[i].index = i;
             	this.oLi[i].onclick = this.tab;
             }

        }

用this.oLi这种表达将oLi变成这个构造函数的属性

  • 第三步,将Tab函数变成它的方法
TabSwich.prototype.tab = function () {
              for (var j = 0; j < this.oLi.length; j++) {
               this.aDiv[j].style.display = "none";
              };
                    
              this.aDiv[tis.index].style.display = "block";
        }
  • 第四步,检查this指针的错误

如果就这样执行,会报错“for (var j = 0; j < this.oLi.length; j++) {”这一行,tab is undefined。

这是因为在构造函数中

this.oLi[i].onclick = this.tab;

这里”tis.tab“的this,指向全局。将li等于tab,那tab就被指向li.我们想让的是这个this是指向构造函数内部的,那我们可以这样做

//先定义一个变量存放this
var _this = this
//然后让this.oLi[i].onclick等于一个匿名函数
this.oLi[i].onclick = function(){
    _this.tab();
}

这样改了之后,我们发现还是会报错,那我们继续检查this,我们发现这里的this有问题

this.aDiv[this.index].style.display = "block";

this.index中的this,我们原意是让它指向oLi的,这面向过程时是正确的,可是我们把它改成面向对象编程的时候,将tab提出来做构造函数的一个方法,在这个方法中this就不再是oLi了,我们可以这样改

this.oLi[i].onclick = function(){
    _this.tab(this);
}
...
TabSwich.prototype.tab = function (oLi) {
...
this.aDiv[oLi.index].style.display = "block";

所以,最终的改写结果是这样的

<!DOCTYPE html>
<html>
<head>
	<title>选项卡--面向对象</title>
	<script type="text/javascript">
        window.onload = function() {
        	var tab1 = new TabSwich();
        }
        function TabSwich() {
             var _this = this
             this.oLi = document.getElementsByTagName('li');
             this.aDiv = document.getElementsByTagName('div');
             for (var i = 0; i < this.oLi.length; i++) {
             	this.oLi[i].index = i;
             	this.oLi[i].onclick = function(){
             		_this.tab(this);
             	}
             }

        }
        TabSwich.prototype.tab = function (oLi) {
              for (var j = 0; j < this.oLi.length; j++) {
               this.aDiv[j].style.display = "none";
              };
                    
              this.aDiv[oLi.index].style.display = "block";
        }
	</script>
	<style type="text/css">
        li {
        	list-style-type: none;
        	display: inline-block;
        	border: 1px solid #000;
        }
        .content{
        	width: 200px;
        	height: 400px;
        	border: 1px solid #000;
        }
	</style>
</head>
<body>
<ul>
	<li>选项1</li>
	<li>选项2</li>
	<li>选项3</li>
</ul>
<div class="content">
	内容1
</div>
<div class="content" style="display:none">
	内容2
</div>
<div class="content" style="display:none">
	内容3
</div>
</body>
</html>

这样的一次实战我们发现,this在面向对象编程时非常重要,虽然我们在平时的 编程中很少用到面向对象编程,但在面试时这是一个大考点,游戏公司大都采用面向对象的语言。

最后,推荐一篇关于this的博客https://kb.cnblogs.com/page/48134/

posted @ 2017-04-06 09:41  叫我小红依吧  阅读(138)  评论(0编辑  收藏  举报