面向對象
一、封裝
<script>
function person(name,age,hobby){
this.name='~~'+name;
this.age=age;
this.hobby='~~'+hobby;
}
person.prototype.showName=function(){
return this.name;
};
person.prototype.showAge=function(){
return this.age;
};
person.prototype.showHobby=function(){
return this.hobby;
};
function worker(name,age,hobby,job){
//屬性繼承
//person(name,age,hobby);
//問題:
//person中的this變成了window
//希望把person中的this變成worker對象
//apply的用法 apply(this(worker),[]) []用arguments代替
//Person.apply(this,name,age)
person.apply(this,arguments);
this.job=job;
};
//方法繼承
//(Worker.prototype = Person.prototype;)
//問題:子類的私有方法,父類也有了
worker.prototype=new person();
//問題:w1.constructor Person
//直接強制賦值過來...
worker.prototype.constructor=worker;
worker.prototype.showJob=function(){
return this.job;
alert(1)
};
var p1=new person('張三',19,'游泳');
var w1=new worker('李四',18,'游泳','搬磚');
alert(p1.showName()+','+p1.showAge()+','+p1.showHobby());
alert(w1.showName()+','+w1.showAge()+','+p1.showHobby()+','+w1.showJob());
</script>
總結
屬性繼承
子類的構造函數中
父類.call(this,arg1,arg2...);
或者
父類.apply(this,[arg1,arg2...]);
或者
父類.apply(this,arguments);
方法繼承
子類.prototype = new 父類();
子類.prototype.constructor = 子類;
二、繼承
1.選項卡
//直接寫方法;
function Tab(id){
this.oBox=document.getElementById(id);
this.aBtn=this.oBox.getElementsByTagName('input');
this.aDiv=this.oBox.getElementsByTagName('div');
var iNow=0;
this.init();//引用方法
}
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只是把變量iNow變成屬性
//后面的this才是真的代表當前的this(aBtn[i])
_this.iNow=this.index;
_this.tab();//引用方法
}
}
};
Tab.prototype.tab=function(){
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';
};
window.onload=function(){
new Tab('box');
};
2.拖拽
<style>
*{margin:0; padding:0;}
#box{
width:200px;
height:200px;
background:red;
position:absolute;
left:0;
top:0;
}
</style>
<script>
function Drag(id){
this.oBox=document.getElementById(id);
this.disX=0;//初始值 寫法規范而已(可有可無)
this.disY=0;//初始值 寫法規范而已(可有可無)
this.init();//面向對象方法
}
//init方法基本類似于接口,引用了fnDown;
Drag.prototype.init=function(){
var _this=this;//存一個this供下面使用
this.oBox.onmousedown=function(ev){
var oEvent=ev || event;
//這里不能直接用this
_this.fnDown(oEvent);//面向對象方法
return false;
}
};
/*Down里面才是主要內容,所以代碼主體構架在Down里面,
方法也是在Down里面引用*/
Drag.prototype.fnDown=function(ev){
var _this=this;
this.disX=ev.clientX-this.oBox.offsetLeft;
this.disY=ev.clientY-this.oBox.offsetTop;
/*onmousemove和onmuseup 本來就是在down里面的,所以即使是
面向對象寫法,也一定要寫在down里面,方法可以提到外面。*/
document.onmousemove=function(ev){
var oEvent=ev || event;
_this.fnMove(oEvent);//面向對象方法
};
document.onmouseup=function(){
_this.fnUp();//面向對象方法
}
};
Drag.prototype.fnMove=function(ev){
this.oBox.style.left=ev.clientX-this.disX+'px';
this.oBox.style.top=ev.clientY-this.disY+'px';
};
Drag.prototype.fnUp=function(){
document.onmousemove=null;
document.onmouseup=null;
};
window.onload=function(){
var n=new Drag('box');
};
</script>
this的一些問題
this具體是什么?不看定義,看調用。
1.優先級
高
new object
定時器 window
事件 /方法 事件/方法所屬于的對象(事件和方法都是一類,可以算平級)
正常調用 window||undefined
低
<script>
function show(){
alert(this);
}
var arr = new Array(1,2,3);
arr.show = show;
//show(); //window
//arr.show(); //array
//new show(); //object
//new arr.show(); //object
//document.onclick = show;
//document.onclick(); //document
document.onclick = arr.show;
//arr.show = document.onclick;
//arr.show();
//new document.onclick(); //object
//document.onclick(); //document
//setTimeout(show,1); //window
//setTimeout(arr.show,1); //window
setTimeout(document.onclick,1);
</script>
2.只管一層
function show(){
alert(this);
}
var arr = [1,2,3];
arr.show = show;
//setTimeout(arr.show,1);
setTimeout(function(){
//alert(this);
//new arr.show();
arr.show();
},1); /*按上面的優先級應是window,現在套了一層就變成字符串了,
這例子可以看出,this只管一層。*/
//document.onclick=show; //document
/*document.onclick = function(){
//alert(this);
//arr.show();
show();
}; //window
document.onclick(); //window*/
//現象同上,this只管一層
3.只看最后一層
<script>
function show(){
alert(this);
}
var arr = [1,2,3];
arr.show = show;
document.onclick = function(){
setTimeout(function(){
new b();
},1);
};
function b(){
new show();
} //彈出Object,這個例子看出this只看最后一層
</script>
三、最后在來說說一些小玩意
1.原型鏈
<script>
//Object.prototype.a = 12; //彈12(其它注釋掉)
//Array.prototype.a = 5; //彈5(其它注釋掉)
var arr = new Array(1,2);
arr.a = 3; //彈3(其它注釋掉)
//都不注釋也彈3(因為先在對象身上找)
alert(arr.a);
/*原型鏈 先在對象身上找,如果找不到,找構造函數,構造函數找不到找父類
,一直往上找,直到找到Object。 如果都沒找到就返回一個undefined*/
</script>
2.找一個值在數組中的位置
Array.prototype.indexOf=function(item){
//存變量是為了提高性能
var len=this.length;//this就是他自己
for(var i=0; i<len; i++){
if(this[i]==item){
return i;
}
}
return -1;
};
var arr=[1,2,3,4,5,6,7,8,9,10,11,12,13];
document.write(arr.indexOf('9')); //彈8
3.去空格
<script>
String.prototype.trim = function(){
//正則去空格
return this.replace(/^\s+|\s+$/g,'');
};
var str = ' 呵呵 ';
alert('|'+str.trim()+'|');
</script>
4.獲取當天星期
<script>
/*Date.prototype.getCnDay = function(){
return '星期'+('日一二三四五六').charAt(this.getDay());
};
var oDate = new Date();
document.write(oDate.getCnDay());*/
/*----------------第二種辦法-----------------*/
Date.prototype.getCnDay = function(){
var arr = ['日','一','二','三','四','五','六'];
return '星期'+arr[this.getDay()];
};
var oDate = new Date();
document.write(oDate.getCnDay());
</script>