Javascript面向(基于)对象编程
一、澄清概念
1.JS中"基于对象=面向对象"
2.JS中没有类(Class),但是它取了一个新的名字叫“原型对象”,因此"类=原型对象"
二、类(原型对象)和对象(实例)的区别与联系
1.类(原型对象)是抽象,是概念的,代表一类事物。
2.对象是具体的,实际的,代表一个具体的事物。
3.类(原型对象)是对象实例的模板,对象实例是类的一个个体。
三、抽象的定义
在定义一个类时,实际上就是把一类事物的共有属性和行为提取出来,形成一个物理模型(模板),这种研究问题的方法称为抽象。
四、JavaScript面向对象三大特征
4.1.封装
封装就是把抽象出来的属性和对属性的操作封装在一起,属性被保护在内部,程序的其它部分只有通过被授权的操作(函数),才能对属性进行操作!
封装的范例:
复制代码
1
2/定义一个Person类/
3functionPerson(_name,_age,_salary){
4//Person类的公开属性,类的公开属性的定义方式是:”this.属性名“
5this.Name=_name;
6//Person类的私有属性,类的私有属性的定义方式是:”var属性名“
7varAge=_age;
8varSalary=_salary;
9
10//定义Person类的公开方法(特权方法),类的公开方法的定义方式是:”this.functionName=function(){.....}“
11this.Show=function(){
12alert("Age="+Age+"\t"+"Salary="+Salary);//在公开方法里面访问类的私有属性是允许的
13}
14/
15定义Person类的私有方法(内部方法),
16类的私有方法的定义方式是:”functionfunctionName(){.....}“,
17或者varfunctionName=function(){....}
18/
19functionprivateFn(){
20alert("我是Person类的私有函数privateFn");
21}
22
23varprivateFn2=function(){
24alert("我是Person类的私有函数privateFn2");
25}
26}
27/通过prototype给可以类的所有对象添加公共(public)方法,
28但是这种方式定义的方法不能去访问类的私有属性和私有方法/
29Person.prototype.Fn=function(){
30alert("访问公共属性this.Name="+this.Name);//访问公共属性,OK的
31//alert("访问私有属性Aag="+Age);//访问私有属性,这里会报错“Age未定义”
32//privateFn();//调用私有方法,这里会报错“缺少对象”
33
34}
35
36varp1=newPerson("孤傲苍狼",24,2300);
37alert("p1.Name="+p1.Name);//访问公有属性,这是可以正常访问的
38alert("p1.Age="+p1.Age+"\t"+"p1.Salary="+p1.Salary);//不能使用类的对象去直接访问类私有属性,这是访问不了的,结果都是undefined
39p1.Show();//调用类的公共函数,这次允许的
40p1.Fn();//调用类的公共函数,这次允许的
41//alert("p1.privateFn():"+p1.privateFn()+" p1.privateFn2():"+p1.privateFn2());//不能使用类的对象去调用类的私有方法,这里会报错”对象不支持此属性或者方法“
42
复制代码
4.2.继承
继承范例:
复制代码
1
2/定义Stu类/
3functionStu(name,age){
4this.Name=name;
5this.Age=age;
6this.Show=function(){
7window.alert("我的名字是:"+this.Name+",今年:"+this.Age);
8}
9this.SayHello=function(){
10window.alert("Hello,"+this.Name);
11}
12}
13
14/定义MidStu类/
15functionMidStu(name,age){
16this.stu=Stu;//MidStu类继承Stu类
17this.stu(name,age);//JS中实际上是通过对象冒充来实现继承的,这句话不能少,因为JS是动态语言,如果不执行,则不能实现继承效果
18/
19从父类继承下来的公共方法,可以根据实际情况选择重写
20/
21//在子类MidStu中重写父类Stu的Show方法
22/this.Show=function(){
23alert("MidStu.Show()");
24}/
25//在子类MidStu中重写父类Stu的SayHello方法
26this.SayHello=function(){
27alert("你好,"+this.Name);
28}
29
30}
31
32varmidStu=newMidStu("孤傲苍狼",24);//创建一个MidStu类实例对象
33alert("访问继承下来的属性Name和Age,midStu.Name="+midStu.Name+",midStu.Name="+midStu.Age);//访问继承下来的属性
34midStu.Show();//调用从父类Stu继承下来的Show方法
35midStu.SayHello();//调用从父类Stu继承下来的SayHello方法,SayHello()在子类中进行了重写,这里调用的是重写过后的SayHello()方法
36
复制代码
运行结果:
4.3.多态
所谓多态,就是指一个引用在不同情况下的多种状态,在Java中多态是指通过指向父类的引用,来调用不同子类中实现的方法。
JS实际上是无态的,是一种动态语言,一个变量的类型是在运行过程中由JS引擎决定的,所以说,JS天然支持多态。
五、JavaScript自定义类(原型对象)的方式
5.1.工厂方法——使用newObject创建对象并添加相关属性
复制代码
1//通过Object直接创建对象
2//varp1=newObject();//创建一个Object对象
3varp1={};//创建一个Object对象,简写
4//动态增加属性、方法
5p1.Name="孤傲苍狼";
6p1.Age=24;
7p1.SayHello=function(){alert("hello,"+p1.Name);};
8p1.SayHello();
9for(varpropertyNameinp1){//对象的成员都是对象的key
10alert(propertyName);
11}
复制代码
5.2.使用构造函数来定义类(原型对象)
基本语法:
复制代码
1function类名(){
2this.属性名;//公共属性
3var属性名;//私有属性
4/凡是定义类的公共属性和公共方法都要使用this/
5//定义类的公共函数
6this.函数名=function(){
7
8}
9//定义类的私有函数
10function函数名(){
11
12}
13}
复制代码
范例:
复制代码
1/定义一个猫类,这种就是使用构造函数来定义类(原型对象)/
2functionCat(){
3this.Name="catName";//public属性
4this.Age;//public属性
5this.Color;//public属性
6varweight=2;//private属性,只能在Cat类内部使用,Cat类的对象无法访问这个私有属性
7//public方法
8this.publicFunction=function(){
9alert(weight);
10alert("猫叫...");
11}
12//private方法,只能在Cat类内部使用,Cat类的对象无法访问这个私有方法
13varprivateFunction=function(){
14alert("私有方法");
15}
16
17
18}
19//如果这样用,那么就当成函数来使用
20Cat();
21//如果这样用,那么就当成类来使用
22varcat1=newCat();
23//cat1就是一个对象(实例)
24alert(cat1.Name);//访问公共属性,弹出默认值catName
25cat1.Name="TomCat";//访问公共属性
26cat1.Age=3;//访问公共属性
27cat1.Color="白色";//访问公共属性
28alert(cat1.weight);//访问私有属性,无法访问,弹出undefined
29alert(cat1.Name+"\t"+cat1.Age+"\t"+cat1.Color);//访问对象的属性方式1:对象名.属性名
30alert(cat1["Name"]+"\t"+cat1["Age"]+"\t"+cat1["Color"]);//访问对象的属性方式2:对象名["属性名"]
31cat1.publicFunction();//调用public方法
32cat1.privateFunction();//调用private方法,报错:对象不支持此属性或方法
33for(varwww.wang027.compropertyincat1){
34document.writeln(property+"\t");
JS中一切都是对象,类(原型对象)其实也是对象,它实际上是Function类的一个实例
复制代码
1document.write("");
2functionPerson(){
3
4}
5/Person.constructor得到的Person类的构造函数如下:
6functionFunction(){
7[nativecode]
8}
9/
10document.writeln("Person.constructor:"+Person.constructor);//Person类的构造函数
11document.writeln("Person:"+Person);
12varp1=newPerson();
13document.writeln("p1.constructor:"+p1.constructor);//”p1.constructor“是得到p1实例的构造函数
14//如何判断某个对象是不是某个类型,采用如下两种方式
15if(p1instanceofPerson){
16document.writeln("p1isPersonok1");
17}
18if(p1.constructor==Person){
19document.writeln("p1isPersonok2");
20}
21
22varnum1=123;
23document.writeln("num1.constructor:"+num1.constructor);
24
25varstr1="abc";
26document.writeln("str1.constructor:"+str1.constructor);
27document.write(" ")
复制代码
运行结果:
Person.constructor:
functionFunction(){
[nativecode]
}
Person:functionPerson(){
}
p1.constructor:functionPerson(){
}
p1isPersonok1
p1isPersonok2
num1.constructor:
functionNumber(){
[nativecode]
}
str1.constructor:
functionString(){
[nativecode]
}
JavaScript——Object类详解
一、Object类介绍
Object类是所有JavaScript类的基类(父类),提供了一种创建自定义对象的简单方式,不再需要程序员定义构造函数。
二、Object类主要属性
1.constructor:对象的构造函数。
2.prototype:获得类的prototype对象,static性质。
三、Object类主要方法
1.hasOwnProperty(propertyName)
判断对象是否有某个特定的属性。必须用字符串指定该属性,例如,obj.hasOwnProperty("name"),返回布尔值。此方法无法检查该对象的原型链中是否具有该属性;该属性必须是对象本身的一个成员。
1varstr="";
2alert("str.hasOwnProperty(\"split\")的结果是:"+str.hasOwnProperty("split"));//returnfalse
3alert("String.prototype.hasOwnProperty(\"split\")的结果是:"+String.prototype.hasOwnProperty("split"));//returntrue
运行结果:
hasOwnProperty的用法不仅仅在此,在Jquery中在编写插件中,少不了的一步,就是初始化参数,其中一个很重要的方法就是$.extend();他的原理就是应用了hasOwnProperty()方法;利用forin循环遍历对象成员中,有没有相同名称的对象成员,有的话就用这个新的对象成员替换掉旧的,通过这种方式,我们就可以通过修改方法中的参数变化,从而控制程序的流程,而对于那些没有改变的部分,仍使用默认值进行控制,我们自己也可以简单的模拟一下这个extend函数,如下
复制代码
1functionextend(target,source){//target旧的source新的
2for(variinsource){
3if(target.hasOwnProperty(i)){
4target[i]=source[i];
5}
6}
7returntarget;
8}
9vara1={"first":1,"second":"lyl","third":"bob"};
10varb1={"third":"leo"};
11extend(a1,b1);
12for(variina1){
13alert(a1[i]);//原本是bob,现在变成leo了
14}
复制代码
2.isPrototypeOf(object)
判断该对象是否为另一个对象的原型。
obj1.isPrototypeOf(obj2);
obj1是一个对象的实例;obj2是另一个将要检查其原型链的对象。原型链可以用来在同一个对象类型的不同实例之间共享功能。如果obj2的原型链中包含obj1,那么isPrototypeOf方法返回true。如果obj2不是一个对象或者obj1没有出现在obj2中的原型链中,isPrototypeOf方法将返回false。
复制代码
1
2functionfoo(){
3this.name=''foo'';
4}
5functionbar(){
6
7}
8bar.prototype=newfoo();
9vargoo=newbar();
10alert(goo.name);//foo
11alert(bar.prototype.isPrototypeOf(goo));//true,在bar的原型链中有当前对象goo,则isPrototypeOf方法返回true
12
复制代码
3.propertyIsEnumerable(propertyName)
通过这个方法我们可以检测出这个对象成员是否是可遍历的,如果是可遍历出来的,证明这个对象就是可以利用forin循环进行遍历的,
格式如下:obj.propertyIsEnumerable(propertyName)
如果propertyName存在于obj中且可以使用一个For…In循环穷举出来,那么propertyIsEnumerable属性返回true。如果object不具有所指定的属性或者所指定的属性不是可列举的,那么propertyIsEnumerable属性返回false。典型地,预定义的属性不是可列举的,而用户定义的属性总是可列举的。
4.toString():返回对象对应的字符串
5.valueOf():返回对象对应的原始类型
以上5个方法都是Object.prototype上定义的,ECMAScript中的所有对象都由Object继承而来,所以在ECMAScript上的所有对象都具有以几个方法
测试代码1:
复制代码
1varp1=newObject();//通过Object直接创建对象
2//为p1对象动态添加属性
3p1.Age=20;
4p1.Name="孤傲苍狼";
5//扩展Object类,为Object类添加一个Show方法
6Object.prototype.Show=function(){
7alert(this.Age+"\t"+this.Name);
8}
9alert(p1.Age);
10p1.Show();
11document.write("");
12document.writeln("p1.constructor:"+p1.constructor);//得到对象的构造函数
13document.writeln("Object.prototype:"+Object.prototype);//得到prototype对象,prototype是静态属性,只能通过"类名.prototype"去访问
14document.writeln("p1.isPrototypeOf(p1):"+p1.isPrototypeOf(p1));
15document.writeln("p1.hasOwnProperty(\"Age\"):"+p1.hasOwnProperty("Age"));
16document.writeln("p1.propertyIsEnumerable(\"Age\"):"+p1.propertyIsEnumerable("Age"));
17document.writeln("p1.toString():"+p1.toString());
18document.writeln("p1.valueOf():"+p1.valueOf());
19document.write(" ");
|
|