js面向对象编程详解
什么是面向对象编程(OOP)?
用对象的思想去写代码,就是面向对象编程
面向对象编程的特点
- 抽象:抓住核心问题(把一样的放在一起)
- 封装:只能通过对象来访问方法(避免乱用代码)
- 继承:从已有对象上继承出新的对象
- 多态:多对象的不同形态
对象的组成
- 方法(行为、操作)——对象下面的函数叫做对象的方法
- 属性——对象下面的变量叫做对象的属性
例:最简单的面向对象
//var obj = {};
var obj = new Object();//创建了一个空对象
obj.name = '小明';//对象下面的变量是对象的属性
obj.showName = function(){//对象下面的函数是对象的方法
alert(obj.name);
}
obj.showName();
上面的代码就是一个完整的面向对象
工厂方式:
- 面向对象中的封装函数
直接看例子
function createPerson(name){
//1.原料
var obj = new Object();
//2.加工
obj.name = name;//属性
obj.showName = function(){//方法
alert( this.name );
};
//3.出厂
return obj;//如果没有写这句代码,则返回值为undefined
}
var p1 = createPerson('小明');
p1.showName();
var p2 = createPerson('小强');
p2.showName();
改成与系统对象类似的写法
- 首字母大写
- new关键字提取
- this指向为新创建的对象
所以上面的代码改为
function CreatePerson(name){
this.name = name;
this.showName = function(){
alert( this.name );
};//省略了 return this;因为这句代码是默认的
}
var p1 = new CreatePerson('小明');
//p1.showName();
var p2 = new CreatePerson('小强');
//p2.showName();
alert( p1.showName == p2.showName ); //false
这里我们需要知道一个概念:构造函数—用来创建对象的函数,叫做构造函数(new后面调用的函数叫做构造函数)
当new去调用一个函数,这个时候函数中的this就是创建出来的对象,而且函数的返回值直接就是this(隐式返回)
我们知道p1.showName和p2.showName其实都是
function CreatePerson(name){
this.name = name;
this.showName = function(){
alert( this.name );
};//省略了 return this;因为这句代码是默认的
}
那么为什么,下面的弹出结果却是false
alert( p1.showName == p2.showName ); //false
这其实就涉及到了,对象的引用问题,因为虽然他们的值相同,但引用不同(也即内存地址不同),所以结果自然也是不同的。(如果你对对象的引用问题有疑问的话,请看js基本类型和引用类型的区别)
所以我们也就发现了这种方式存在的问题,所以我们引入了原型(prototype)的概念
原型的概念:
- 重写对象的方法,让相同方法在内存中存在一份(去改写对象下面公用的方法或者属性,让公用的方法或者属性在内存中存在一份)
原型的优先级要低于普通方法。为了便于记忆,我们可以采用类比的方法
- 原型可以看成css中的class,而普通方法可以看成css中的style
接下来我们通过原型改写工厂方式
原则:
- 相同的属性和方法可以加在原型上
混合的编程模式
function CreatePerson(name){
this.name = name;
}
CreatePerson.prototype.showName = function(){alert( this.name );
}
var p1 = new CreatePerson(‘小明’);
var p2 = new CreatePerson(‘小强’);
alert( p1.showName == p2.showName ); //true
总结面向对象的写法
构造函数加属性,原型加方法
function 构造函数(){
this.属性
}
构造函数.原型.方法 = function(){};
var 对象1 = new构造函数();
对象.方法
下面举一个例子:面向对象之选项卡自动播放+点击按钮播放
原则:刚开始的时候先写出普通的写法,然后改成面向对象的写法
—普通方法的变形
- 尽量不要出现函数嵌套函数
- 可以有全局变量
- 把onload中不是赋值的语句放到单独的函数中
—改成面向对象
- 全局变量就是属性
- 函数就是方法
- onload中创建对象
- 改this指向问题(注意:事件或者是定时器,尽量让面向对象中的this指向对象)
普通的写法此处就不再赘述,直接上面相对象的写法
HTML代码
<div id="wrap1">
<input type="button" class="active" value="按钮1"/>
<input type="button" value="按钮2"/>
<input type="button" value="按钮3"/>
<div style="display:block">aaaaaa</div>
<div>vvvvvvvvvvvvvv</div>
<div>ddddddddddddddddddd</div>
</div>
<div id="wrap2">
<input type="button" class="active" value="按钮1"/>
<input type="button" value="按钮2"/>
<input type="button" value="按钮3"/>
<div style="display:block">aaaaaa</div>
<div>vvvvvvvvvvvvvv</div>
<div>ddddddddddddddddddd</div>
</div>
CSS代码
<style>
#wrap1,#wrap2{width:400px; height:400px; margin:10px; padding:10px;}
#wrap1 div,#wrap2 div{width:300px; height:300px; padding:10px; border:1px solid brown; display:none; margin:5px;}
.active{background:red;}
</style>
JS面向对象的代码
<script>
window.onload = function(){//window.onload中创建对象以及初始方法的调用
var t1 = new Tab('wrap1');
t1.init();
var t2 = new Tab('wrap2');
t2.init();
t2.autoPlay();
}
function Tab(id){//构造函数里面获取到对象的属性
this.oBox = document.getElementById(id);
this.aBtn = this.oBox.getElementsByTagName('input');
this.aDiv = this.oBox.getElementsByTagName('div');
this.iNow = 0;
}
Tab.prototype.init = function(){//方法写在构造函数的原型下面
var This = this;
for(var i=0; i<this.aBtn.length; i++){
this.aBtn[i].index = i;
this.aBtn[i].onclick = function(){
This.change(this);//事件调用函数时,注意要改this的指向问题
}
}
}
Tab.prototype.change = function(obj){
this.iNow = obj.index;
for(var i=0; i<this.aBtn.length; i++){
this.aBtn[i].className = '';
this.aDiv[i].style.display = 'none';
}
obj.className = 'active';
this.aDiv[obj.index].style.display = 'block';
}
Tab.prototype.autoPlay = function(){
var This = this;
setInterval(function(){//定时器中的函数也要注意改this的指向问题
This.iNow++;
if(This.iNow==This.aBtn.length){
This.iNow = 0;
}
for(var i=0; i<This.aBtn.length;i++){
This.aBtn[i].className = '';
This.aDiv[i].style.display = 'none';
}
This.aBtn[This.iNow].className='active';
This.aDiv[This.iNow].style.display = 'block';
},2000);
}
</script>
今天先总结这些,后续还会有面向对象其他知识的总结
还没有评论,来说两句吧...