什麼是物件導向程式設計(OOP)?用物件的想法去寫程式碼,就是物件導向程式設計。
物件導向程式設計的特點
#抽象:抓住核心問題
封裝:只能透過物件來存取方法
#繼承:從已有物件繼承出新的物件
多態:多物件的不同形態
物件的組成
屬性:物件下面的變數叫做物件的屬性
方法:物件下面的函數叫做物件的方法
var arr = [];
arr.number = 10; //对象下面的变量:叫做对象的属性//alert( arr.number );//alert( arr.length );arr.test = function(){ //对象下面的函数 : 叫做对象的方法alert(123);
};
arr.test();//方法arr.push();//方法arr.sort();
var obj=new Object();//创建一个空的对象obj.name='小明'; //属性obj.showName=function(){ //方法alert(this.name);//this指向obj } obj.showName();//小明
var obj1=new Object();//创建一个空的对象obj1.name='小明'; //属性obj1.showName=function(){ //方法alert(this.name);//this指向obj }
obj1.showName();//小明var obj2=new Object();//创建一个空的对象obj2.name='小灰'; //属性obj2.showName=function(){ //方法alert(this.name);//this指向obj }
obj2.showName();//小灰
,可透過工廠方式來解決這個問題
//工厂方式 : 封装函数function createPerson(name){var obj = new Object(); obj.name = name; obj.showName = function(){ alert( this.name ); };return obj; }var p1 = createPerson('小明'); p1.showName();var p2 = createPerson('小强'); p2.showName();
建立物件用工廠方式來實現,可以傳遞參數,由於創建物件都是使用Object的原生建構子來實現的,因此無法辨識物件類型
建構子模式 -------- ------------ 給一個物件添加方法
//new 后面调用的函数叫构造函数function CreatePerson(name){this.name=name;this.showName=function(){
alert(this.name);
}
}var p1=new CreatePerson('小明');//当new去调用一个函数时,函数中的this就是创建出来的对象而函数中的返回值就是this p1.showName();var p2=new CreatePerson('小强');
p2.showName();
#沒有明確的建立物件
直接將屬性與方法賦給this物件
####沒有return語句############### ###上面範例中:CreatePerson建構函式產生的兩個物件p1與p2都是CreatePerson的實例############雖然建構子解決了上面工廠方式的問題,但它一樣存在缺點,就是在創建物件時,每個物件都有一套自己的方法,###每定義一個函數都實例化了一個物件###############例如:## #######function CreatePerson(name){ this.name = name;this.showName = function(){ alert( this.name ); }; }var p1 = new CreatePerson('小明');//p1.showName();var p2 = new CreatePerson('小强');//p2.showName();alert( p1.showName == p2.showName ); //false 它们的值相同,地址不同
var a = [1,2,3];var b = [1,2,3]; alert( a == b ); //false 值相同,地址不同var a = 5;var b = a;b += 3 alert(b); //8alert(a); //5 基本类型 : 赋值的时候只是值的复制
var a = [1,2,3];var b = a;b.push(4); alert(b); //[1,2,3,4]alert(a); //[1,2,3,4] 对象类型 : 赋值不仅是值的复制,而且也是引用的传递
var a = [1,2,3];var b = a; b = [1,2,3,4]; alert(b); //[1,2,3,4]alert(a); //[1,2,3]
对比上面的几个例子,不难看出基本类型和对象类型的区别了,对象类型的赋值不仅是值的复制,也是引用的传递;提到了对象的引用应该很清楚上述p1.showName==p2.showName为何会返回结果是false
原型模式(prototype) -------------------- 给一类对象添加方法
原型(prototype):重写对象下面公用的属性或方法,让公用的属性或方法在内存中只存在一份(提高性能),也就是说所有在原型对象中创建的属性或方法都直接被所有对象实例共享。
原型:类比css中的class
普通方法:类比css中的style
var arr = [1,2,3,4,5];var arr2 = [2,2,2,2,2]; Array.prototype.sum = function(){//原型prototype : 要写在构造函数的下面var result = 0;for(var i=0;i<this.length;i++){ result += this[i]; }return result; }; alert( arr.sum() ); //15alert( arr2.sum() ); //10
原型优先级:如果在实例中添加了一个属性,而该属性与实例原型中的一个属性同名,该属性将会屏蔽原型中的那个属性
例子1:
var arr = []; arr.number = 10; Array.prototype.number = 20; alert(arr.number);//10
例子2:
Array.prototype.a=12;//原型属性var arr=[1,2,3]; alert(arr.a);//12arr.a=5;//实例属性alert(arr.a);//5
工厂方式之原型
function CreatePerson(name){//普通方法this.name=name; } CreatePerson.prototype.showName=function(){//原型alert(this.name); }var p1=new CreatePerson('小明'); p1.showName();var p2=new CreatePerson('小强'); p2.showName(); alert( p1.showName== p2.showName);//true
由上述例子中:p1.showName== p2.showName弹出的结果是true,可见原型解决了构造函数中“每定义一个函数都实例化了一个对象”的问题
原型的运用
选项卡实例:
<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>选项卡</title><style>#div1 div{width:400px;height:300px;border:1px solid #ccc;overflow: hidden;display: none;margin: 15px 0;}#div1 input{color: #fff;width:100px;height:40px;background: darkseagreen;border:none;font-size: 14px;letter-spacing: 5px;}#div1 p{font-size: 20px;line-height: 24px;text-align: center;color:darkgreen;}#div1 .title{padding: 0;font-weight: bold;}#div1 .active{background:sandybrown;color:#fff;}</style><script>window.onload=function(){var oDiv=document.getElementById('div1');var aInput=oDiv.getElementsByTagName('input');var aDiv=oDiv.getElementsByTagName('div');var i=0;for(i=0;i<aInput.length;i++){ aInput[i].index=i; aInput[i].onmousemove=function(){for(var i=0;i<aInput.length;i++){ aInput[i].className=''; aDiv[i].style.display='none'; } aInput[this.index].className='active'; aDiv[this.index].style.display='block'; } } }</script></head><body><div id="div1"><input class="active" type="button" value="五言律诗"><input type="button" value="七言律诗"><input type="button" value="五言绝句"><input type="button" value="七言绝句"><div style="display: block;"><p class="title">落 花</p><p class="author">李商隐</p><p>高阁客竟去,小园花乱飞。</p><p>参差连曲陌,迢递送斜晖。</p><p>肠断未忍扫,眼穿仍欲归。</p><p>芳心向春尽,所得是沾衣。</p></div><div><p class="title">蜀 相</p><p class="author">杜甫</p><p>丞相祠堂何处寻,锦官城外柏森森。</p><p>映阶碧草自春色,隔叶黄鹂空好音。</p><p>三顾频烦天下计,两朝开济老臣心。</p><p>出师未捷身先死,长使英雄泪满襟。</p></div><div><p class="title">八阵图</p><p class="author">杜甫</p><p>功盖三分国,名成八阵图。</p><p>江流石不转,遗恨失吞吴。</p></div><div><p class="title">泊秦淮</p><p class="author">杜牧</p><p>烟笼寒水月笼沙,夜泊秦淮近酒家。</p><p>商女不知亡国恨,隔江犹唱后庭花。</p></div></div></body></html>
效果(鼠标经过按钮时选项卡切换):
面向对象选项卡:
<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>选项卡</title><style>#div1 div,#div2 div{width:400px;height:300px;border:1px solid #ccc;overflow: hidden;display: none;margin: 15px 0;}#div1 input,#div2 input{color: #fff;width:100px;height:40px;background: darkseagreen;border:none;font-size: 14px;letter-spacing: 5px;}#div1 p,#div2 p{font-size: 20px;line-height: 24px;text-align: center;color:darkgreen;}#div1 .title,#div2 .title{padding: 0;font-weight: bold;}#div1 .active,#div2 .active{background:sandybrown;color:#fff;}</style><script>window.onload=function(){var t1=new TabSwitch('div1'); t1.switch(); var t2=new TabSwitch('div2');//面向对象的复用性 t2.switch(); t2.autoPlay();/*alert(t2.switch==t1.switch);//ture*/}function TabSwitch(id){this.oDiv=document.getElementById(id);this.aInput=this.oDiv.getElementsByTagName('input');this.aDiv=this.oDiv.getElementsByTagName('div');this.iNow=0;//自定义属性} TabSwitch.prototype.switch=function(){//原型for(var i=0;i<this.aInput.length;i++){var This=this;//将指向面向对象的this保存下来this.aInput[i].index=i;this.aInput[i].onmousemove=function(){ This.tab(this);//This指向面向对象 this指向this.aInput[i] } } } TabSwitch.prototype.tab=function(obj){//原型for(var i=0;i<this.aInput.length;i++){this.aInput[i].className='';this.aDiv[i].style.display='none'; }this.aInput[obj.index].className='active';this.aDiv[obj.index].style.display='block'; }//自动播放 TabSwitch.prototype.autoPlay=function(){var This=this; setInterval(function(){if(This.iNow==This.aInput.length-1){ This.iNow=0; }else{ This.iNow++; }for(var i=0;i<This.aInput.length;i++){ This.aInput[i].className=''; This.aDiv[i].style.display='none'; } This.aInput[This.iNow].className='active'; This.aDiv[This.iNow].style.display='block'; },1000); }</script></head><body><div id="div1"><input class="active" type="button" value="五言律诗"><input type="button" value="七言律诗"><input type="button" value="五言绝句"><input type="button" value="七言绝句"><div style="display: block;"><p class="title">落 花</p><p class="author">李商隐</p><p>高阁客竟去,小园花乱飞。</p><p>参差连曲陌,迢递送斜晖。</p><p>肠断未忍扫,眼穿仍欲归。</p><p>芳心向春尽,所得是沾衣。</p></div><div><p class="title">蜀 相</p><p class="author">杜甫</p><p>丞相祠堂何处寻,锦官城外柏森森。</p><p>映阶碧草自春色,隔叶黄鹂空好音。</p><p>三顾频烦天下计,两朝开济老臣心。</p><p>出师未捷身先死,长使英雄泪满襟。</p></div><div><p class="title">八阵图</p><p class="author">杜甫</p><p>功盖三分国,名成八阵图。</p><p>江流石不转,遗恨失吞吴。</p></div><div><p class="title">泊秦淮</p><p class="author">杜牧</p><p>烟笼寒水月笼沙,夜泊秦淮近酒家。</p><p>商女不知亡国恨,隔江犹唱后庭花。</p></div></div><div id="div2"><input class="active" type="button" value="五言律诗"><input type="button" value="七言律诗"><input type="button" value="五言绝句"><input type="button" value="七言绝句"><div style="display: block;"><p class="title">落 花</p><p class="author">李商隐</p><p>高阁客竟去,小园花乱飞。</p><p>参差连曲陌,迢递送斜晖。</p><p>肠断未忍扫,眼穿仍欲归。</p><p>芳心向春尽,所得是沾衣。</p></div><div><p class="title">蜀 相</p><p class="author">杜甫</p><p>丞相祠堂何处寻,锦官城外柏森森。</p><p>映阶碧草自春色,隔叶黄鹂空好音。</p><p>三顾频烦天下计,两朝开济老臣心。</p><p>出师未捷身先死,长使英雄泪满襟。</p></div><div><p class="title">八阵图</p><p class="author">杜甫</p><p>功盖三分国,名成八阵图。</p><p>江流石不转,遗恨失吞吴。</p></div><div><p class="title">泊秦淮</p><p class="author">杜牧</p><p>烟笼寒水月笼沙,夜泊秦淮近酒家。</p><p>商女不知亡国恨,隔江犹唱后庭花。</p></div></div></body></html>
效果(第二个选项卡加了一个自动切换功能):
面向对象中this的问题
一般会出现问题的情况有两种:
定时器
事件
例子1:
//定时器function Aaa(){ var _this=this;//将当前this值保存this.a=12; setInterval(function(){//定时器中this指向window _this.show(); },1000); } Aaa.prototype.show=function(){ alert(this.a); }var obj=new Aaa();//12
例子2:
<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>面向对象中this的问题-----事件</title><script>function Bbb(){var _this=this;this.b=5; document.getElementById('btn1').onclick=function(){//点击事件 _this.show(); }}
Bbb.prototype.show=function(){ alert(this.b); } window.onload=function(){var p2=new Bbb(); }</script></head><body><input id="btn1" type="button" value="按钮"></body></html>
上面两个是分别对定时器和事件中this问题的解决方法,即将指向对象的this保存到了_this中,在嵌套函数中调用对象的方法或属性时用 _this.属性 或 _this.方法
再来个实例:
拖拽效果:
<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>最初写的拖拽效果</title> <style> #div1{ width:100px; height:100px; background: red; position: absolute; } </style><script>window.onload=function(){var oDiv=document.getElementById('div1'); oDiv.onmousedown=function(ev){var oEvent=ev||event;var disX=0;var disY=0;var disX=oEvent.clientX-oDiv.offsetLeft;var disY=oEvent.clientY-oDiv.offsetTop; document.onmousemove=function(ev){var oEvent=ev||event; oDiv.style.left=oEvent.clientX-disX+'px'; oDiv.style.top=oEvent.clientY-disY+'px'; }; document.onmouseup=function(){ document.onmousemove=null; document.onmouseup=null; };return false; } }</script></head><body><div id="div1"></div></body></html>
面向对象的拖拽
<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>面向对象写的拖拽效果</title><style>#div1{width:100px;height:100px;background: red;position: absolute;}</style><script>window.onload=function(){var p=new Darg('div1'); p.init(); }function Darg(id){this.oDiv=document.getElementById(id); //属性this.disX=0;//属性this.disY=0;//属性} Darg.prototype.init=function(){//原型 方法var This=this;this.oDiv.onmousedown=function(ev){var oEvent=ev||event; This.fnDown(oEvent);return false; } } Darg.prototype.fnDown=function(ev){//原型 方法var This=this;this.disX=ev.clientX-this.oDiv.offsetLeft;this.disY=ev.clientY-this.oDiv.offsetTop; document.onmousemove=function(ev){var oEvent=ev||event; This.fnMove(oEvent); }; document.onmouseup=function(){ This.fnUp(); }; } Darg.prototype.fnMove=function(ev){//原型this.oDiv.style.left=ev.clientX-this.disX+'px';this.oDiv.style.top=ev.clientY-this.disY+'px'; } Darg.prototype.fnUp=function(){//原型 document.onmousemove=null; document.onmouseup=null; }</script></head><body><div id="div1"></div></body></html>
以上是什麼是物件導向程式設計(OOP)?物件導向程式設計的特點的詳細內容。更多資訊請關注PHP中文網其他相關文章!