面向对象:
一花一世界,一叶一菩提
一朵花是一个宇宙,一个人也是一个宇宙,世间万物不管大小都是一个世界,对于生长在花上的昆虫,花就是他的地球,对于生长在地球外的比地球还大的生物来说,地球只是一个皮球,人要有佛性后世间万物不要只看外表,他都是一个世界。(请让我也文艺一下,已吐!!!)
面向对象和面向过程:
面向对象:直白的说,就是将你在前端领域所遇到的问题(大部分可能是业务),通过封装,继承,多态等类似的方法进行抽象的实现,在使用过程中,通过简单的实例化就可以将业务对象赋予对应的状态和方法从而调用。
面向过程:实际上就是将你的业务逻辑按照先后顺寻进行整理,将每一个小的逻辑认为是一个模块,并套用面向对象的方法。
面向对象的特性:
封装:把事物和核心提取出来,进行抽象
多态:js里面没什么用, 子级可以继承多个父亲的特征
继承:
子级可以继承父级的方法功能
js中没有类的概念,js的继承是用过原型来实现
问:为什么要用面向对象,原因很多,但就前端开发来说我个人觉得有两个优点。
第一,是将松散的JS代码进行整合,便于后期的维护
第二,是让我们的代码适应更多的业务逻辑。
问;什么是对象对象:
js中对象有很多,比如Array,String,Math,Date,map,json等等!
对象身上都有属性和方法。
属性:物体的特征
身高 三围 性别 年龄
方法:物体的行为,功能
哭,跳,吃,
注:关于面向对象你要知道:对于每个对象来说,属性不一样,方法是一样,而且咱们都会用,但是咱们从来不会去管他是怎么实现!
问:什么叫做面向对象:
只管用,不用管他的内部的构成
问:为什么要用面向对象:
为提高效率
问:方法和函数:
函数是独立的存在,自由的
方法是依附于对象身上
问:属性和变量:
变量是单独存在的,自由的
属性是依附于对象身上
注:在我们编写面向对象中:面向对象不难,最难的是this
this:
当前触发事件的对象(元素)
触发这个函数的对象(看上下文)
js中怎么创造对象:
var obj=new Object(); //空白的对象
下面我们正常写一个函数,并且在里面new出一个对象,给加上属性和方法。
function CreatePeople(name,age){
var obj=new Object(); //准备空白的对象
//添加属性
obj.name=name;
obj.age=age;
//添加方法
obj.showName=function(){
return this.name
};
obj.pop=function(){
return this.age
};
return obj
};
var p1=CreatePeople('李鹏','12');
alert(p1.showName())
但是目前写面构造函数不是这样写。
创造对象的函数,叫做构造函数,构造函数特征 首字母大写。正常封装一个函数,然后在调用的时候加上new出来,new干的事情 造一个空白的对象赋值this,然后默认返回this。这种也叫工厂模式,new出来的叫做实例。
function CreatePeople(name,age){
//var obj = new Object(); 准备材料
//new 造一个空白的对象给this
//添加属性 加工
obj.name=name;
obj.age=age;
//添加方法
obj.showName=function(){
return this.name
};
obj.pop=function(){
return this.age
};
//默认返回this
//return obj 出厂
};
var p1=new CreatePeople('李鹏','12');
alert(p1.showName())
但是现在我们都会用:构造/原型混合模式 Structure / prototype hybrid model
prototype是原型,每一个对象身上都会有,储存方法。
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.showName=function(){
return alert('我叫'+this.name)
};
Person.prototype.showAge=function(){
return alert('我的年龄是'+this.age)
};
var p1=new Person('李鹏','12');
p1.showName();
例子:下面我们写一个面向对象的选项卡:
function Tab(id){
this.oBox=document.getElementById(id);
this.aDiv=this.oBox.getElementsByTagName('div');
this.aBtn=this.oBox.getElementsByTagName('input');
for(var i=0;i<this.aBtn.length;i++){
var _this=this;
this.aBtn[i].index=i;
this.aBtn[i].onclick=function(){
_this.fnClick(this);
}
//this.aBtn[i].onclick=this.fnClick;
}
}
Tab.prototype.fnClick=function(obj){
for(var i=0;i<this.aBtn.length;i++){
this.aBtn[i].className='';
this.aDiv[i].className='';
}
obj.className='on';
this.aDiv[obj.index].className='on';
};
window.onload=function(){
new Tab('box');//用id是box的div把选项卡包住。
}
面向对象最大的特点是继承。
属性的继承:
可以用call和apply的方法来继承,第一个参数都是纠正this的指向,后面是参数,两者的区别是apply传参可以用数组,想到了什么,arguments对吧,所有哪个方便,你知道的。
fn.call(this的指向,参数1,参数2.....);
fn.apply(this的指向,[参数1,参数2.....]);
这其中我们要改变this的指向,通过call和apply来继承属性,然后把this的指向转向当前这个对象。
岔开:说一下this的问题
this:谁调用他,或者这个调用属于谁,包一层的时候this会变。
this的优先级:
new -> object
定时器 -> window
事件 -> 触发事件的对象
方法 -> 方法属于谁
其他/直接调用的
方法的继承:
方法1:
Student.prototype=Person.prototype;
//问题:发生了引用,父级也有子级的方法
方法2:
for(var name in Person.prototype){
Student.prototype[name]=Person.prototype[name];
}
//问题:alert(s1 instanceof Person);
//学生不是人,创造出来的对象不属于构造函数了,
方法3:
Student.prototype=new Person();
//问题:不认亲爹了
//解决:
Student.prototype.constructor=Student; //让构造函数直接等于他自己。
instanceof 一个对象属于某个类 obj instanceof Object
constructor 检测某个对象是什么构造出来的 如:oDate.constructor==Date;
//构造函数
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.showName=function(){
return '我叫'+this.name
};
Person.prototype.showAge=function(){
return '我的年龄是'+this.age
};
var p1=new Person('李鹏','12');
//要继承的函数
function Student(name,age,job){
//this
Person.apply(this,[name,age]);//继承属性
this.job=job;
}
Student.prototype=new Person();//继承方法
Student.prototype.constructor=Student;//然后让构造函数直接等于他自己
Student.prototype.showJob=function(){
return '我的职业是'+this.job
};
var s1=new Student('李小鹏','6','学生');
例子:一个普通选项卡,一个带自动播放的选项卡
function Tab(id){
if(!id)return;//这个是一会下面关系到继承方法,没有传参所以我们一开始判断一下,不然待会会报错,找不到id。
this.iNow=0;
this.oBox=document.getElementById(id);
this.aInp=this.oBox.getElementsByTagName('input');
this.aDiv=this.oBox.getElementsByTagName('div');
var _this=this;
for(var i=0;i<this.aInp.length;i++){
this.aInp[i].index=i;
this.aInp[i].onclick=function(){
_this.fnClick(this);
}
}
}
Tab.prototype.fnClick=function(obj){
this.iNow=obj.index;
for(var i=0;i<this.aInp.length;i++){
this.aInp[i].className='';
this.aDiv[i].className='';
}
obj.className='on';
this.aDiv[obj.index].className='on';
}
function AutoTab(){
Tab.apply(this,arguments);
var _this=this;
this.timer=null;
this.timer=setInterval(function(){
_this.next();
},1000);
this.oBox.onmouseover=function(){
clearInterval(_this.timer)
}
this.oBox.onmouseout=function(){
_this.timer=setInterval(function(){
_this.next();
},1000)
}
}
AutoTab.prototype=new Tab();
AutoTab.prototype.constructor=AutoTab;
AutoTab.prototype.next=function(){
this.iNow++;
if(this.iNow==this.aInp.length){
this.iNow=0;
}
this.fnClick(this.aInp[this.iNow])
};
window.onload=function(){
new Tab('box');
new AutoTab('box2');
};
ES6新版面向对象:
class Person{
constructor(name,age){ //直接写属性
this.name=name;
this.age=age;
}
showName(){ //直接可以写方法
return this.name
}
showAge(){
return this.age
}
}
//var xiaoming=new Person('小明','16');
class Student extends Person{ //继承
constructor(name,age,job='student'){
super(name,age); //直接就继承了属性和方法
this.job=job;
}
showJob(){
return this.job
}
}
var xiaohua=new Student('小花','39');
var xiaolv=new Student('小绿','45','student');
alert(xiaohua.showJob())
以上,结束。
网友评论