js面向对象编程
对象是什么? 对象数据类型:对象就是带有属性和方法的 数据类型
面向对象里面有什么:类和对象 (有什么关系)
类是对象的抽象,而对象是类的具体实例
基本数据类型 string numberboolean null undefined
Array 对象
对象数据类型有一个自定义属性
var num = 10; // 变量
var arr = []; // 数组
arr.index = 10; // 数组arr 的 一个 index 属性
但是有个问题,我们想要某些属性或者方法的时候,用数组不合适。
arr.lenght .
我们想要自己id属性和方法。 要求这个一定是个对象才行。
如何声明对象
我们有两种声明对象的方式.
var obj = new Object();
但是我们更提倡用第二种方法:字面量式声明对象
var obj = {};
var obj = {}; // 声明对象
obj.name = "刘德华"; // 属性
obj.age = 55;
obj.showName = function() { // 声明方法 方法一定带有 ()
alert("俺是刘德华");
}
obj.showAge = function() {
alert("俺今年18岁");
}
如何使用对象
console.log(obj.name); // 调用属性
console.log(obj.age);
obj.showName(); // 调用方法
obj.showAge();
1、什么是面向对象 (面向对象是一种通用思想,并非只有编程中能用,任何事情都可以用)
l
什么是对象 (
对象数据类型:对象就是带有属性和方法的 数据类型
)
l电视机工作原理?
l
对象是一个整体,对外提供一些操作
l
什么是面向对象
l
使用对象时,只关注对象提供的功能,不关注其内部细节
l
比如
JQuery
l
面向对象是一种通用思想,并非只有编程中能用,任何事情都可以用
l
什么是对象 (
对象数据类型:对象就是带有属性和方法的 数据类型
)
l电视机工作原理?
l
对象是一个整体,对外提供一些操作
l
什么是面向对象
l
使用对象时,只关注对象提供的功能,不关注其内部细节
l
比如
JQuery
l
面向对象是一种通用思想,并非只有编程中能用,任何事情都可以用
2、js中的面向对象
l
面向对象编程
(OOP)
的特点
l
抽象:抓住核心问题
l
封装:不考虑内部实现,只考虑功能使用
l
继承:从已有对象上,继承出新的对象
l
多重继承
l
多态
l
对象的组成
l
方法
——
函数:过程、动态的
l
属性
——
变量:状态、静态的
<script>
var a=12;//变量:自由的,不属于任何人
alert(a);
var arr=[1,2,3,4,5,6];
arr.a=12;//属性:属于一个对象的
alert(arr.a);
</script>
<script>
function aaa()//函数:自由
{
alert('abc');
}
var arr=[1,2,3,4];
arr.aaa=function()//方法:属于一个对象
{
alert('abc');
};
aaa();
arr.aaa();
</script>
l
面向对象编程
(OOP)
的特点
l
抽象:抓住核心问题
l
封装:不考虑内部实现,只考虑功能使用
l
继承:从已有对象上,继承出新的对象
l
多重继承
l
多态
l
对象的组成
l
方法
——
函数:过程、动态的
l
属性
——
变量:状态、静态的
<script>
var a=12;//变量:自由的,不属于任何人
alert(a);
var arr=[1,2,3,4,5,6];
arr.a=12;//属性:属于一个对象的
alert(arr.a);
</script>
<script>
function aaa()//函数:自由
{
alert('abc');
}
var arr=[1,2,3,4];
arr.aaa=function()//方法:属于一个对象
{
alert('abc');
};
aaa();
arr.aaa();
</script>
3、写一个面向对象程序
l
为对象添加方法和属性
l
this
详解,事件处理中
this
的本质
l
window
l
this——
函数属于谁
l
不能在系统对象中随意附加方法、属性,否则会覆盖已有方法、属性
l
object
对象
<script>
var arr=[1,2,3,4];
arr.a=12;
arr.show=function()
{
alert(this.a);
};
oDiv.onclick=function()
{
alert(this);
};
arr.show();
</script>
上面的this是属于谁?
<script>
window.show=function()
{
alert(this);
};
show();
</script>
会弹出什么?
上面的属性和方法都是加在数组对象上的,我们有个原则:
不能在系统对象中随意附加方法、属性,否则会覆盖已有方法、属性。所以这里,我们利用object来创建新对象:
<script>
var obj=newObject();
obj.name='blue';
obj.qq='258248832';
obj.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
obj.showName();
obj.showQQ();
</script>
如果有两个对象呢:
<script>
var obj=newObject();
obj.name='blue';
obj.qq='258248832';
obj.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
obj.showName();
obj.showQQ();
var obj2=newObject();
obj2.name='张三';
obj2.qq='5468978546';
obj2.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj2.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
obj2.showName();
obj2.showQQ();
</script>
上面的写法虽然没有问题,但是代码冗余,改进一下:构建函数(该函数的功能是构建对象)
<script>
function createPerson(name, qq)//构造函数
{
var obj=newObject();
obj.name=name;
obj.qq=qq;
obj.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
return obj;
}
var obj=createPerson('blue','258248832');
obj.showName();
obj.showQQ();
var obj2=createPerson('张三','45648979879');
obj2.showName();
obj2.showQQ();
</script>
l
为对象添加方法和属性
l
this
详解,事件处理中
this
的本质
l
window
l
this——
函数属于谁
l
不能在系统对象中随意附加方法、属性,否则会覆盖已有方法、属性
l
object
对象
<script>
var arr=[1,2,3,4];
arr.a=12;
arr.show=function()
{
alert(this.a);
};
oDiv.onclick=function()
{
alert(this);
};
arr.show();
</script>
上面的this是属于谁?
<script>
window.show=function()
{
alert(this);
};
show();
</script>
会弹出什么?
上面的属性和方法都是加在数组对象上的,我们有个原则:
不能在系统对象中随意附加方法、属性,否则会覆盖已有方法、属性。所以这里,我们利用object来创建新对象:
<script>
var obj=newObject();
obj.name='blue';
obj.qq='258248832';
obj.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
obj.showName();
obj.showQQ();
</script>
如果有两个对象呢:
<script>
var obj=newObject();
obj.name='blue';
obj.qq='258248832';
obj.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
obj.showName();
obj.showQQ();
var obj2=newObject();
obj2.name='张三';
obj2.qq='5468978546';
obj2.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj2.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
obj2.showName();
obj2.showQQ();
</script>
上面的写法虽然没有问题,但是代码冗余,改进一下:构建函数(该函数的功能是构建对象)
<script>
function createPerson(name, qq)//构造函数
{
var obj=newObject();
obj.name=name;
obj.qq=qq;
obj.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
return obj;
}
var obj=createPerson('blue','258248832');
obj.showName();
obj.showQQ();
var obj2=createPerson('张三','45648979879');
obj2.showName();
obj2.showQQ();
</script>
4、工厂方式
l
什么是工厂
l
原料
l
加工
l
出厂
l
工厂方式
l
用构造函数创建一个类
l
什么是类、对象(实例):模具和零件
<script>
function createPerson(name, qq)//构造函数
{
//原料
var obj=newObject();
//加工
obj.name=name;
obj.qq=qq;
obj.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
//出厂
return obj;
}
var obj=createPerson('blue','258248832');
obj.showName();
obj.showQQ();
var obj2=createPerson('张三','45648979879');
obj2.showName();
obj2.showQQ();
</script>
l
什么是工厂
l
原料
l
加工
l
出厂
l
工厂方式
l
用构造函数创建一个类
l
什么是类、对象(实例):模具和零件
<script>
function createPerson(name, qq)//构造函数
{
//原料
var obj=newObject();
//加工
obj.name=name;
obj.qq=qq;
obj.showName=function()
{
alert('我的名字叫:'+this.name);
};
obj.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
//出厂
return obj;
}
var obj=createPerson('blue','258248832');
obj.showName();
obj.showQQ();
var obj2=createPerson('张三','45648979879');
obj2.showName();
obj2.showQQ();
</script>
5、工厂方式遇到的问题
l
问题
l
没有
new
l
函数重复定义
l
加上
new
l
偷偷做了两件事
l
替你创建了一个空白对象
l
替你返回了这个对象
l
new
和
this
上面的这个对象有什么缺点?1.var date=new Date(); 这里没有用new。第二个:函数的重复(系统资源浪费,因为每个对象都有一个方法)
下面先解决第一个问题,加上new:
<script>
function createPerson(name, qq)//构造函数
{
//系统偷偷替咱们做:
//var this=new Object();
//加工
this.name=name;
this.qq=qq;
this.showName=function()
{
alert('我的名字叫:'+this.name);
};
this.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
//也会偷偷做一些:
//return this;
}
var obj=new createPerson('blue','258248832');
var obj2=new createPerson('张三','45648979879');
obj.showName();
obj.showQQ();
//alert(obj.showName==obj2.showName);
</script>
l
问题
l
没有
new
l
函数重复定义
l
加上
new
l
偷偷做了两件事
l
替你创建了一个空白对象
l
替你返回了这个对象
l
new
和
this
上面的这个对象有什么缺点?1.var date=new Date(); 这里没有用new。第二个:函数的重复(系统资源浪费,因为每个对象都有一个方法)
<script>
function createPerson(name, qq)//构造函数
{
//系统偷偷替咱们做:
//var this=new Object();
//加工
this.name=name;
this.qq=qq;
this.showName=function()
{
alert('我的名字叫:'+this.name);
};
this.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
//也会偷偷做一些:
//return this;
}
var obj=new createPerson('blue','258248832');
var obj2=new createPerson('张三','45648979879');
obj.showName();
obj.showQQ();
//alert(obj.showName==obj2.showName);
</script>
6、原型——prototype
l
什么是原型
l
原型是
class
,修改他可以影响一类元素
l
在已有对象中加入自己的属性、方法
l
原型修改对已有对象的影响
l
为
Array
添加
sum
方法
l
给对象添加方法,类似于行间样式
l
给原型添加方法,类似于
class
l
原型的小缺陷
l
无法限制覆盖
解决第二个问题:原型
<script>
var arr1=newArray(12,55,34,78,676);
var arr2=newArray(12,33,1);
Array.prototype.sum=function()//class
//arr1.sum=function () //行间样式
{
var result=0;
for(var i=0;i<this.length;i++)
{
result+=this[i];
}
return result;
};
alert(arr1.sum());
alert(arr2.sum());//?
</script>
什么是类和对象?
var arr=new Date();
arr叫做对象,Date叫做类。
构造函数和原型一起做:
<script>
function createPerson(name, qq)//构造函数
{
//系统偷偷替咱们做:
//var this=new Object();
//加工
this.name=name;
this.qq=qq;
//也会偷偷做一些:
//return this;
}
createPerson.prototype.showName=function()//原型
{
alert('我的名字叫:'+this.name);
};
createPerson.prototype.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
var obj=new createPerson('blue','258248832');
var obj2=new createPerson('张三','45648979879');
/*obj.showName();
obj.showQQ();
obj2.showName();
obj2.showQQ();*/
alert(obj.showName==obj2.showName);
</script>
规范写法:
<script>
functionCreatePerson(name, qq)//构造函数
{
this.name=name;
this.qq=qq;
}
CreatePerson.prototype.showName=function()//原型
{
alert('我的名字叫:'+this.name);
};
CreatePerson.prototype.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
var obj=newCreatePerson('blue','258248832');
var obj2=newCreatePerson('张三','45648979879');
/*obj.showName();
obj.showQQ();
obj2.showName();
obj2.showQQ();*/
alert(obj.showName==obj2.showName);
</script>
l
什么是原型
l
原型是
class
,修改他可以影响一类元素
l
在已有对象中加入自己的属性、方法
l
原型修改对已有对象的影响
l
为
Array
添加
sum
方法
l
给对象添加方法,类似于行间样式
l
给原型添加方法,类似于
class
l
原型的小缺陷
l
无法限制覆盖
解决第二个问题:原型
<script>
var arr1=newArray(12,55,34,78,676);
var arr2=newArray(12,33,1);
Array.prototype.sum=function()//class
//arr1.sum=function () //行间样式
{
var result=0;
for(var i=0;i<this.length;i++)
{
result+=this[i];
}
return result;
};
alert(arr1.sum());
alert(arr2.sum());//?
</script>
什么是类和对象?
<script>
function createPerson(name, qq)//构造函数
{
//系统偷偷替咱们做:
//var this=new Object();
//加工
this.name=name;
this.qq=qq;
//也会偷偷做一些:
//return this;
}
createPerson.prototype.showName=function()//原型
{
alert('我的名字叫:'+this.name);
};
createPerson.prototype.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
var obj=new createPerson('blue','258248832');
var obj2=new createPerson('张三','45648979879');
/*obj.showName();
obj.showQQ();
obj2.showName();
obj2.showQQ();*/
alert(obj.showName==obj2.showName);
</script>
规范写法:
<script>
functionCreatePerson(name, qq)//构造函数
{
this.name=name;
this.qq=qq;
}
CreatePerson.prototype.showName=function()//原型
{
alert('我的名字叫:'+this.name);
};
CreatePerson.prototype.showQQ=function()
{
alert('我的QQ号:'+this.qq);
};
var obj=newCreatePerson('blue','258248832');
var obj2=newCreatePerson('张三','45648979879');
/*obj.showName();
obj.showQQ();
obj2.showName();
obj2.showQQ();*/
alert(obj.showName==obj2.showName);
</script>
l
用混合方式构造对象
l
混合的的构造函数
/
原型方式
l
Mixed Constructor Function/Prototype Method
l
原则
l
构造函数:加属性
l
原型:加方法
l
对象命名规范
l
类名首字母大写
二、面向对象的选项卡
先用之前面向过程的方法写一次选项卡:
<!DOCTYPE HTML>
<html>
<head>
<metacharset="utf-8">
<title>无标题文档</title>
<style>
#div1 input {background:white;}
#div1 input.active {background:yellow;}
#div1 div {width:200px; height:200px; background:#CCC; display:none;}
</style>
<script>
window.onload=function()
{
var oDiv=document.getElementById('div1');
var aBtn=oDiv.getElementsByTagName('input');
var aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].index=i;
aBtn[i].onclick=function()
{
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].className=''
aDiv[i].style.display='none';
}
this.className='active';
aDiv[this.index].style.display='block';
};
}
};
</script>
</head>
<body>
<divid="div1">
<inputclass="active"type="button"value="aaa"/>
<inputtype="button"value="bbb"/>
<inputtype="button"value="ccc"/>
<divstyle="display:block;">aaa</div>
<div>dfsadf</div>
<div>erwqerwe</div>
</div>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<metacharset="utf-8">
<title>无标题文档</title>
<style>
#div1 input {background:white;}
#div1 input.active {background:yellow;}
#div1 div {width:200px; height:200px; background:#CCC; display:none;}
</style>
<script>
window.onload=function()
{
var oDiv=document.getElementById('div1');
var aBtn=oDiv.getElementsByTagName('input');
var aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].index=i;
aBtn[i].onclick=function()
{
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].className=''
aDiv[i].style.display='none';
}
this.className='active';
aDiv[this.index].style.display='block';
};
}
};
</script>
</head>
<body>
<divid="div1">
<inputclass="active"type="button"value="aaa"/>
<inputtype="button"value="bbb"/>
<inputtype="button"value="ccc"/>
<divstyle="display:block;">aaa</div>
<div>dfsadf</div>
<div>erwqerwe</div>
</div>
</body>
</html>
1、把嵌套函数抽出来。
- 函数不能嵌套
- 变量变成全局变量
<script>
var aBtn=null;
var aDiv=null;
window.onload=function()
{
var oDiv=document.getElementById('div1');
aBtn=oDiv.getElementsByTagName('input');
aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].index=i;
aBtn[i].onclick=fnClick;
}
};
function fnClick()
{
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].className=''
aDiv[i].style.display='none';
}
this.className='active';
aDiv[this.index].style.display='block';
}
</script>
- 函数不能嵌套
- 变量变成全局变量
<script>
var aBtn=null;
var aDiv=null;
window.onload=function()
{
var oDiv=document.getElementById('div1');
aBtn=oDiv.getElementsByTagName('input');
aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].index=i;
aBtn[i].onclick=fnClick;
}
};
function fnClick()
{
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].className=''
aDiv[i].style.display='none';
}
this.className='active';
aDiv[this.index].style.display='block';
}
</script>
2、去掉onload,写上this
<script>
//var aBtn=null;
//var aDiv=null;
functionTabSwitch(id)
{
var oDiv=document.getElementById(id);
this.aBtn=oDiv.getElementsByTagName('input');
this.aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++)
{
this.aBtn[i].index=i;
this.aBtn[i].onclick=fnClick;
}
};
TabSwitch.prototype.fnClick=function()
{
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].className=''
this.aDiv[i].style.display='none';
}
this.className='active';
this.aDiv[this.index].style.display='block';
}
</script>
3、修复bug
<script>
window.onload=function()
{
newTabSwitch('div1');
};
functionTabSwitch(id)
{
var oDiv=document.getElementById(id);
this.aBtn=oDiv.getElementsByTagName('input');
this.aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].index=i;
this.aBtn[i].onclick=this.fnClick;
}
};
TabSwitch.prototype.fnClick=function()
{
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].className=''
this.aDiv[i].style.display='none';
}
oBtn.className='active';
this.aDiv[oBtn.index].style.display='block';
}
</script>
<script>
window.onload=function()
{
newTabSwitch('div1');
};
functionTabSwitch(id)
{
var _this=this;
var oDiv=document.getElementById(id);
this.aBtn=oDiv.getElementsByTagName('input');
this.aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].index=i;
this.aBtn[i].onclick=function()
{
_this.fnClick();
};
}
};
TabSwitch.prototype.fnClick=function()
{
//alert(this);
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].className=''
this.aDiv[i].style.display='none';
}
oBtn.className='active';
this.aDiv[oBtn.index].style.display='block';
}
</script>
修复完:
<script>
window.onload=function()
{
newTabSwitch('div1');
};
functionTabSwitch(id)
{
var _this=this;
var oDiv=document.getElementById(id);
this.aBtn=oDiv.getElementsByTagName('input');
this.aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].index=i;
this.aBtn[i].onclick=function()
{
_this.fnClick(this);
};
}
};
TabSwitch.prototype.fnClick=function(oBtn)
{
//alert(this);
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].className=''
this.aDiv[i].style.display='none';
}
oBtn.className='active';
this.aDiv[oBtn.index].style.display='block';
}
</script>
<script>
//var aBtn=null;
//var aDiv=null;
functionTabSwitch(id)
{
var oDiv=document.getElementById(id);
this.aBtn=oDiv.getElementsByTagName('input');
this.aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++)
{
this.aBtn[i].index=i;
this.aBtn[i].onclick=fnClick;
}
};
TabSwitch.prototype.fnClick=function()
{
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].className=''
this.aDiv[i].style.display='none';
}
this.className='active';
this.aDiv[this.index].style.display='block';
}
</script>
3、修复bug
<script>
window.onload=function()
{
newTabSwitch('div1');
};
functionTabSwitch(id)
{
var oDiv=document.getElementById(id);
this.aBtn=oDiv.getElementsByTagName('input');
this.aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].index=i;
this.aBtn[i].onclick=this.fnClick;
}
};
TabSwitch.prototype.fnClick=function()
{
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].className=''
this.aDiv[i].style.display='none';
}
oBtn.className='active';
this.aDiv[oBtn.index].style.display='block';
}
</script>
<script>
window.onload=function()
{
newTabSwitch('div1');
};
functionTabSwitch(id)
{
var _this=this;
var oDiv=document.getElementById(id);
this.aBtn=oDiv.getElementsByTagName('input');
this.aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].index=i;
this.aBtn[i].onclick=function()
{
_this.fnClick();
};
}
};
TabSwitch.prototype.fnClick=function()
{
//alert(this);
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].className=''
this.aDiv[i].style.display='none';
}
oBtn.className='active';
this.aDiv[oBtn.index].style.display='block';
}
</script>
<script>
window.onload=function()
{
newTabSwitch('div1');
};
functionTabSwitch(id)
{
var _this=this;
var oDiv=document.getElementById(id);
this.aBtn=oDiv.getElementsByTagName('input');
this.aDiv=oDiv.getElementsByTagName('div');
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].index=i;
this.aBtn[i].onclick=function()
{
_this.fnClick(this);
};
}
};
TabSwitch.prototype.fnClick=function(oBtn)
{
//alert(this);
for(var i=0;i<this.aBtn.length;i++)
{
this.aBtn[i].className=''
this.aDiv[i].style.display='none';
}
oBtn.className='active';
this.aDiv[oBtn.index].style.display='block';
}
</script>