面向对象
一、封装
<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>