javascript面向对象技术基础(五)
创始人
2024-07-29 01:20:17
0

看了很多介绍javascript面向对象技术的文章,很晕.为什么?不是因为写得不好,而是因为太深奥.javascript中的对象还没解释清楚怎么回事,一上来就直奔主题,类/继承/原型/私有变量。结果呢,看了大半天,有了一个大概的了解,细细一回味,好像什么都没懂。

这篇文章是参考<>第7,8,9章而写成的,我也会尽量按照原书的结构来说明javascript的面向对象技术(对象/数组->函数-->类/构造函数/原型).对一些我自己也拿捏不准的地方,我会附上原文的英文语句,供大家参考.

类变量/类方法/实例变量/实例方法

先补充一下以前写过的方法:

在javascript中,所有的方法都有一个call方法和apply方法.这两个方法可以模拟对象调用方法.它的***个参数是对象,后面的
参数表示对象调用这个方法时的参数.比如我们定义了一个方法f(),然后调用下面的语句:

  1. f.call(o, 1, 2); 

 

作用就相当于

  1. o.m = f;  
  2. o.m(1,2);  
  3. delete o.m; 

 

举个例子:

Js代码:

  1. function Person(name,age) { //定义方法  
  2. this.name = name;  
  3. this.age = age;  
  4. }  
  5. var o = new Object(); //空对象  
  6. alert(o.name + "_" + o.age); //undefined_undefined  
  7. Person.call(o,"sdcyst",18); //相当于调用:o.Person("sdcyst",18)  
  8. alert(o.name + "_" + o.age); //sdcyst_18  
  9. Person.apply(o,["name",89]);//apply方法作用同call,不同之处在于传递参数的形式是用数组来传递  
  10. alert(o.name + "_" + o.age); //name_89 

实例变量和实例方法都是通过实例对象加"."操作符然后跟上属性名或方法名来访问的,但是我们也可以为类来设置方法或变量,
这样就可以直接用类名加"."操作符然后跟上属性名或方法名来访问.定义类属性和类方法很简单:

Js代码

  1. Person.counter = 0; //定义类变量,创建的Person实例的个数  
  2. function Person(name,age) {  
  3. this.name = name;  
  4. this.age = age;  
  5. Person.counter++; //没创建一个实例,类变量counter加1  
  6. };  
  7. Person.whoIsOlder = function(p1,p2) { //类方法,判断谁的年龄较大  
  8. if(p1.age > p2.age) {  
  9. return p1;  
  10. } else {  
  11. return p2;  
  12. }  
  13. }  
  14. var p1 = new Person("p1",18);  
  15. var p2 = new Person("p2",22);  
  16. alert("现在有 " + Person.counter + "个人"); //现在有2个人  
  17. var p = Person.whoIsOlder(p1,p2);  
  18. alert(p.name + "的年龄较大"); //p2的年龄较大  

 

prototype属性的应用:

下面这个例子是根据原书改过来的.假设我们定义了一个Circle类,有一个radius属性和area方法,实现如下:

Js代码:

  1. function Circle(radius) {  
  2. this.radius = radius;  
  3. this.area = function() {  
  4. return 3.14 * this.radius * this.radius;  
  5. }  
  6. }  
  7. var c = new Circle(1);  
  8. alert(c.area()); //3.14 

假设我们定义了100个Circle类的实例对象,那么每个实例对象都有一个radius属性和area方法,实际上,除了radius属性,每个Circle类的实例对象的area方法都是一样,这样的话,我们就可以把area方法抽出来定义在Circle类的prototype属性中,这样所有的实例对象就可以调用这个方法,从而节省空间.

Js代码

  1. function Circle(radius) {  
  2. this.radius = radius;  
  3. }  
  4. Circle.prototype.area = function() {  
  5. return 3.14 * this.radius * this.radius;  
  6. }  
  7. var c = new Circle(1);  
  8. alert(c.area()); //3.14  

 

现在,让我们用prototype属性来模拟一下类的继承:首先定义一个Circle类作为父类,然后定义子类PositionCircle.

Js代码
 

  1. function Circle(radius) { //定义父类Circle   
  2. this.radius = radius;   
  3. }   
  4. Circle.prototype.area = function() { //定义父类的方法area计算面积   
  5. return this.radius * this.radius * 3.14;   
  6. }    
  7. function PositionCircle(x,y,radius) { //定义类PositionCircle   
  8. this.x = x; //属性横坐标   
  9. this.y = y; //属性纵坐标   
  10. Circle.call(this,radius); //调用父类的方法,相当于调用this.Circle(radius),设置PositionCircle类的   
  11. //radius属性   
  12. }   
  13. PositionCircle.prototype = new Circle(); //设置PositionCircle的父类为Circle类   
  14. var pc = new PositionCircle(1,2,1);   
  15. alert(pc.area()); //3.14   
  16. //PositionCircle类的area方法继承自Circle类,而Circle类的   
  17. //area方法又继承自它的prototype属性对应的prototype对象   
  18. alert(pc.radius); //1 PositionCircle类的radius属性继承自Circle类   
  19. /* 注意:在前面我们设置PositionCircle类的prototype属性指向了一个Circle对象,因此pc的prototype属性继承了Circle对象的prototype属性,而Circle对象的constructor属性(即Circle对象对应的prototype对象的constructor属性)是指向Circle的,所以此处弹出   
  20. 的是Circ.   
  21. */   
  22. alert(pc.constructor); //Circle   
  23. /*为此,我们在设计好了类的继承关系后,还要设置子类的constructor属性,否则它会指向父类   
  24. 的constructor属性   
  25. */   
  26. PositionCircle.prototype.constructor = PositionCircle   
  27. alert(pc.constructor); //PositionCircle  

【编辑推荐】

  1. javascript面向对象技术基础(一)
  2. javascript面向对象技术基础(二)
  3. javascript面向对象技术基础(三)
  4. javascript面向对象技术基础(四)

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...