javascript面向对象的编程.docx
- 文档编号:26979627
- 上传时间:2023-06-24
- 格式:DOCX
- 页数:20
- 大小:52.14KB
javascript面向对象的编程.docx
《javascript面向对象的编程.docx》由会员分享,可在线阅读,更多相关《javascript面向对象的编程.docx(20页珍藏版)》请在冰豆网上搜索。
javascript面向对象的编程
javascript面向对象的编程
一.Javascript面向对象概述:
Javascript是一种面向(基于)对象的动态脚本语言,是一种基于对象(Object)和事件驱动(EventDriven)并具有安全性能的脚本语言。
他具有面向对象语言所特有的各种特性,比如封装、继承及多态等。
但对于大多数人说,我们只把javascript做为一个函数式语言,只把他用于一些简单的前端数据输入验证以及实现一些简单的页面动态效果等,我们没能完全把握动态语言的各种特性。
在很多优秀的Ajax框架中,比如ExtJS、JQuery等,大量使用了javascript的面向对象特性,要使用好ext技术,javascript的高级特性,面向对象语言特性是我们必须完全把握的。
二.对象的基本概念:
1.对象:
属性主要是指对象内部所包含的一些自己的特征,而方法则表示对象可以具有的行为,对象的属性和方法都叫做对象的成员。
2.面向对象:
面相对象(ObjectOriented)是对象编成技术的一种,它具有3个基本特性:
封装性,继承性,多态性,而且这3个特典缺一不可。
3.基于对象:
面向对象和基于对象都实现了封装型,但那是面向对象具有继承性和多态性,而基于对象不具有继承性和多态性。
4.基于对象的javascript。
(1.5以前的版本都是基于对象的,2.0以后的版本全面支持面向对象)
三.对象的属性和方法
一个Javascript对象是由属性和方法两个基本的要素构成。
1.属性
对象的属性是对象自身包含的一组变量。
对象可以包含很多属性,对象的属性是指该类对象的实例所共同具有的特征。
例1:
varCat={
name:
'',
color:
''
}
假定我们把猫看成一个对象,它有"名字"和"颜色"两个属性。
2.方法
方法实际是Javascript对象的属于函数的属性,它表示对象所具有的行为。
每个对象都有
自己的方法集,方法使用于属性相似的方式进行存取,其语法格式如下.
对象名.方法名(参数列表);doucument.write();
假定我们把猫看成一个对象,它有"名字"和"颜色"两个属性。
四.JavaScript的内部类
动态对象:
使用“对象实例名.成员”的格式来访问其属性和方法。
静态对象:
直接使用“对象名.成员”的格式来访问其属性和方法。
●Object类(对象)
●Number类(对象)
●String类(对象)
●Math类(对象)
●Date类(对象)
●toString方法
4.1Object类
Object类是所有javascript类的基类,提供了一种创建自定义对象的简单方式,不需要程序员再定义构造函数。
主要属性:
constructor-对象的构造函数
prototype-获得类的prototype对象,static性质
主要方法:
hasOwnProperty(property)-是否属于本类定义的属性
isPrototypeOf(object)-是否是指定类的prototype
propertyIsEnumerable(property)-是否可例举的属性
toString()-返回对象对应的字符串
valueOf()-返回对象对应的原始类型值
functiongetAttributeValue(attr){}varperson=newObject();person.name="zs";person.age=18;getAttributeValue("name");alert(person[attr]);
getAttributeValue("age");
4.2Number类
Number类代表数据类,包含一些静态的成员及数值处理的方法。
静态属性:
MAX_VALUE、MIN_VALUE、NEGATIVE_INFINITY、POSITIVE_INFINITY、NaN主要方法:
toFixed(n)-取小数位数,自动四舍五入
toPrecision(n)-是否是指定类的prototype
propertyIsEnumerable(property)-是否可例举的属性
toString()-返回对象对应的字符串
valueOf()-返回对象对应的原始类型值
varoNumberObject=newNumber(99);
alert(oNumberObject.toFixed
(2));//outputs“99.00”
4.3String类
●length属性
●anchor、big、bold、fontcolor、link等方法
●charAt方法
注意:
一个字符串中的第一个字符的索引位置为0,依次类推。
●charCodeAt方法注意:
返回的结果是字符的unicode编码。
●concat方法,连接字符串
●indexOf方法及lastIndexOf方法
●match、search方法
●replace、split方法
●slice方法
4.4Math类说明:
str1.slice(0)和str1.slice(0,-1)都是返回整个字符串。
●substr、substring方法substring方法返回的内容不包含结束位置的字符。
●toLowerCase、toUpperCase方法
Math对象是一个静态类,不能使用new关键字创建对象实例,应直接使用“对象名.成员”的格式来访问其属性或方法,例如,varnum=Math.random();
属性:
●E,代表数学常数e,约等于2.718。
●LN10,代表10的自然对数,约等于2.302。
●LN2,代表2的自然对数,约等于0.693。
●PI,代表数学常数∏的值,约等于3.14159。
●SQRT1-2,代表2的平方根分之一,约等于0.707。
●SQRT2,代表2的平方根,约等于1.414。
方法:
●abs方法,返回数字的绝对值。
●sin、cos方法,分别返回数字的正弦、余弦值。
●asin、acos方法,分别返回数字的反正弦、反余弦值。
●random方法,返回介于0和1之间的伪随机数
●round()返回某数四舍五入之后的整数
●pow()返回0和1之间的一个伪随机数
●min()返回两数间的较小值
●max()返回两数间的较大值
4.5Date类
●构造方法:
Date()、Date(dateVal)、Date(year,month,date[,hours[,minutes[,
seconds[,ms]]]])
●parse方法,分析一个表示日期时间的字符串,返回它所表示的时间值,该值以自1970
年1月1日0点0分0秒算起的毫秒值表示。
parse方法属于一个静态方法。
●toGMTString方法,返回Date对象实例所表示的日期的字符串形式,该字符串使用
格林尼治标准时间(GMT)格式,例如,“05Jan199600:
00:
00GMT”。
●getYear返回年份值
●getMonth返回月份值
●getDate返回日期
●getDay返回星期几
●getHours返回小时数
●getMinutes返回分钟数
●getSeconds返回秒数
●getMilliseconds返回完整的时间
●getTime方法,返回自1970年1月1日0点0分0秒算起,至Date对象实例代表
的时间为止的毫秒数。
varcurrent_time=newDate();
varstrDate=current_time.getYear()+"年";
strDate+=current_time.getMonth()+"月";
strDate+=current_time.getDate()+"日";
strDate+=current_time.getHours()+":
";
strDate+=current_time.getMinutes()+":
";
strDate+=current_time.getSeconds();
alert(strDate);
设置时间的方法
Date对象也同时提供了与读取时间方法相对应的设置时间的方法,用于对日期和时间进行自定义设置。
setDate()改变Date对象的日期
setHours()改变小时数
setMinutes()改变分钟数
setMonth()改变月份
setSeconds()改变秒数
setTime()改变完整的时间
setYear()改变年份
4.6toString方法
toString方法是JavaScript中的所有内部对象的一个成员方法,它的主要作用就是将对象中的数据转换成某种格式的字符串来表示,具体的转换方式取决于对象的类型。
举例:
varx=328;alert("hex=“+x.toString(16)+"bin=“+x.toString
(2));
4.7Array类
三种构造方法:
●Array()
●Array(4)
●Array(3.5,"abc",3)
数组排序例子:
vararr=newArray();
arr[0]=3.5;
arr[1]="abc"
arr[2]=3;
arr.sort();
varx,str="";
for(xinarr)
{
}
alert(str);
4.8用户自定义类及对象
五.Javascript面向对象编程
(一):
封装
Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。
但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。
那么,如果我们要把"属性"(property)和"方法"(method),封装成一个对象,甚至要从原型对象生成一个实例对象,我们应该怎么做呢?
1.生成对象的原始模式str+=x+":
“+arr[x]+"\n";
假定我们把猫看成一个对象,它有"名字"和"颜色"两个属性。
varCat={
name:
'',
color:
''
}
现在,我们需要根据这个原型对象,生成两个实例对象。
varcat1={};//创建一个空对象
cat1.name="大毛";//按照原型对象的属性赋值
cat1.color="黄色";
varcat2={};
cat2.name="二毛";
cat2.color="黑色";
好了,这就是最简单的封装了。
但是,这样的写法有两个缺点,一是如果多生成几个实例,写起来就非常麻烦;二是实例与原型之间,没有任何办法,可以看出有什么联系。
2.原始模式的改进
我们可以写一个函数,解决代码重复的问题。
functionCat(name,color){
return{
name:
name,
color:
color
}
}
然后生成实例对象,就等于是在调用函数:
varcat1=Cat("大毛","黄色");
varcat2=Cat("二毛","黑色");
这种方法的问题依然是,cat1和cat2之间没有内在的联系,不能反映出它们是同一个原型对象的实例。
3.构造函数模式
为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式。
所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。
对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。
比如,猫的原型对象现在可以这样写,
functionCat(name,color){
this.name=name;
this.color=color;
}
我们现在就可以生成实例对象了。
varcat1=newCat("大毛","黄色");
varcat2=newCat("二毛","黑色");
alert(cat1.name);//大毛
alert(cat1.color);//黄色
这时cat1和cat2会自动含有一个constructor属性,指向它们的构造函数。
alert(cat1.constructor==Cat);//true
alert(cat2.constructor==Cat);//true
Javascript还提供了一个instanceof运算符,验证原型对象与实例对象之间的关系。
alert(cat1instanceofCat);//true
alert(cat2instanceofCat);//true
4.构造函数模式的问题
构造函数方法很好用,但是存在一个浪费内存的问题。
请看,我们现在为Cat对象添加一个不变的属性"type"(种类),再添加一个方法eat(吃老鼠)。
那么,原型对象Cat就变成了下面这样:
functionCat(name,color){
this.name=name;
this.color=color;
this.type="猫科动物";
this.eat=function(){alert("吃老鼠");};
}
还是采用同样的方法,生成实例:
varcat1=newCat("大毛","黄色");
varcat2=newCat("二毛","黑色");
alert(cat1.type);//猫科动物
cat1.eat();//吃老鼠
表面上好像没什么问题,但是实际上这样做,有一个很大的弊端。
那就是对于每一个实例对象,type属性和eat()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。
这样既不环保,也缺乏效率。
alert(cat1.eat==cat2.eat);//false
能不能让type属性和eat()方法在内存中只生成一次,然后所有实例都指向那个内存地址呢?
回答是可以的。
5.Prototype模式
Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。
这个对象的所
有属性和方法,都会被构造函数的实例继承。
这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。
functionCat(name,color){
this.name=name;
this.color=color;
}
Cat.prototype.type="猫科动物";
Cat.prototype.eat=function(){alert("吃老鼠")};
然后,生成实例。
varcat1=newCat("大毛","黄色");
varcat2=newCat("二毛","黑色");
alert(cat1.type);//猫科动物
cat1.eat();//吃老鼠
这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。
alert(cat1.eat==cat2.eat);//true
6.Prototype模式的验证方法
6.1isPrototypeOf()
这个方法用来判断,某个proptotype对象和某个实例之间的关系。
alert(Cat.prototype.isPrototypeOf(cat1));//true
alert(Cat.prototype.isPrototypeOf(cat2));//true
6.2hasOwnProperty()
每个实例对象都有一个hasOwnProperty()方法,用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性。
alert(cat1.hasOwnProperty("name"));//true
alert(cat1.hasOwnProperty("type"));//false
6.3in运算符
in运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性。
alert("name"incat1);//true
alert("type"incat1);//true
in运算符还可以用来遍历某个对象的所有属性。
for(varpropincat1){alert("cat1["+prop+"]="+cat1[prop]);}
六.Javascript面向对象编程
(二):
封装
下面要介绍的是,如何生成一个"继承"多个对象的实例。
比如,现在有一个"动物"对象的构造函数,
functionAnimal(){
this.species="动物";
}
还有一个"猫"对象的构造函数,
functionCat(name,color){
this.name=name;
this.color=color;
}
怎样才能使"猫"继承"动物"呢?
1.构造函数绑定
最简单的方法,大概就是使用call或apply方法,将父对象的构造函数绑定在子对象上,也就是在子对象构造函数中加一行:
functionCat(name,color){
Animal.apply(this,arguments);
this.name=name;
this.color=color;
}
varcat1=newCat("大毛","黄色");
alert(cat1.species);//动物
2.prototype模式
更常见的做法,则是使用prototype属性。
如果"猫"的prototype对象,指向一个Animal的实例,那么所有"猫"的实例,就能继承Animal了。
Cat.prototype=newAnimal();
Cat.prototype.constructor=Cat;
varcat1=newCat("大毛","黄色");
alert(cat1.species);//动物
代码的第一行,我们将Cat的prototype对象指向一个Animal的实例。
Cat.prototype=newAnimal();
它相当于完全删除了prototype对象原先的值,然后赋予一个新值。
但是,第二行又是什么意思呢?
Cat.prototype.constructor=Cat;
原来,任何一个prototype对象都有一个constructor属性,指向它的构造函数。
也就是说,Cat.prototype这个对象的constructor属性,是指向Cat的。
我们在前一步已经删除了这个prototype对象原来的值,所以新的prototype对象没有
constructor属性,所以我们必须手动加上去,否则后面的"继承链"会出问题。
这就是第二行
的意思。
总之,这是很重要的一点,编程时务必要遵守。
下文都遵循这一点,即如果替换了prototype对象,
o.prototype={};
那么,下一步必然是为新的prototype对象加上constructor属性,并将这个属性指回原来的构造函数。
o.prototype.constructor=o;
3.直接继承prototype
由于Animal对象中,不变的属性都可以直接写入Animal.prototype。
所以,我们也可以让Cat()跳过Animal(),直接继承Animal.prototype。
现在,我们先将Animal对象改写:
functionAnimal(){}
Animal.prototype.species="动物";
Cat.prototype=Animal.prototype;
Cat.prototype.constructor=Cat;
varcat1=newCat("大毛","黄色");
alert(cat1.species);//动物
与前一种方法相比,这样做的优点是效率比较高(不用执行和建立Animal的实例了),比较省内存。
缺点是Cat.prototype和Animal.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype。
然后,将Cat的prototype对象,然后指向Animal的prototype对象,这样就完成了继承。
所以,上面这一段代码其实是有问题的。
请看第二行
Cat.prototype.constructor=Cat;
这一句实际上把Animal.prototype对象的constructor属性也改掉了!
alert(Animal.prototype.constructor);//Cat
4.利用空对象作为中介
由于"直接继承prototype"存在上述的缺点,所以可以利用一个空对象作为中介。
varF=function(){};
F.prototype=Animal.prototype;
Cat.prototype=newF();
Cat.prototype.constructor=Cat;
F是空对象,所以几乎不占内存。
这时,修改Cat的prototype对象,就不会影响到Animal的prototype对象。
alert(Animal.prototype.constructor);//Animal
5.prototype模式的封装函数
我们将上面的方法,封装成一个函数,便于使用。
functionextend(Child,Parent){
varF=function(){};
F.prototype=Parent.prototype;
Child.prototype=newF();
Child.prototype.constructor=Child;
Child.uber=Parent.prototype;
}
使用的时候,方法如下
extend(Cat,Animal);
varcat1=newCat("大毛","黄色");
alert(cat1.species);//动物
这个extend函数,就是YUI库如何实现继承的方法。
另外,说明一点。
函数体最后一行
Child.uber=Parent.prototype;
意思是为子对象设一个uber属性,这个属性直接指向父对象的prototype属性。
这等于是在子对象上打开一条
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- javascript 面向 对象 编程