配色: 字号:
Javascript面向(基于)对象编程
2016-08-25 | 阅:  转:  |  分享 
  
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("
");

献花(0)
+1
(本文系thedust79首藏)