javascript物件導向技術基礎(五)

來源:互聯網
上載者:User

 

類變數/類方法/執行個體變數/執行個體方法
先補充一下以前寫過的方法:
在javascript中,所有的方法都有一個call方法和apply方法.這兩個方法可以類比對象調用方法.它的第一個參數是對象,後面的
參數表示對象調用這個方法時的參數(ECMAScript specifies two methods that are defined for all functions, call()
and apply(). These methods allow you to invoke a function as if it were a method of some other object. The first
argument to both call() and apply() is the object on which the function is to be invoked; this argument becomes
the value of the this keyword within the body of the function. Any remaining arguments to call() are the values
that are passed to the function that is invoked).比如我們定義了一個方法f(),然後調用下面的語句:
f.call(o, 1, 2);
作用就相當於
o.m = f;
o.m(1,2);
delete o.m;
舉個例子:

 

Js代碼
  1. function Person(name,age) {  //定義方法   
  2.     this.name = name;   
  3.     this.age = age;   
  4. }   
  5. var o = new Object();   //Null 物件   
  6. alert(o.name + "_" + o.age); //undefined_undefined   
  7.   
  8. Person.call(o,"sdcyst",18); //相當於調用:o.Person("sdcyst",18)   
  9. alert(o.name + "_" + o.age); //sdcyst_18   
  10.   
  11. Person.apply(o,["name",89]);//apply方法作用同call,不同之處在於傳遞參數的形式是用數組來傳遞   
  12. alert(o.name + "_" + o.age); //name_89  

 

function Person(name,age) {  //定義方法    this.name = name;    this.age = age;}var o = new Object();   //Null 物件alert(o.name + "_" + o.age); //undefined_undefinedPerson.call(o,"sdcyst",18); //相當於調用:o.Person("sdcyst",18)alert(o.name + "_" + o.age); //sdcyst_18Person.apply(o,["name",89]);//apply方法作用同call,不同之處在於傳遞參數的形式是用數組來傳遞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.   
  8. Person.whoIsOlder = function(p1,p2) { //類方法,判斷誰的年齡較大   
  9.     if(p1.age > p2.age) {   
  10.         return p1;   
  11.     } else {   
  12.         return p2;   
  13.     }   
  14. }   
  15.   
  16. var p1 = new Person("p1",18);   
  17. var p2 = new Person("p2",22);   
  18.   
  19. alert("現在有 " + Person.counter + "個人");  //現在有2個人   
  20. var p = Person.whoIsOlder(p1,p2);   
  21. alert(p.name + "的年齡較大");   //p2的年齡較大  

 

Person.counter = 0;   //定義類變數,建立的Person執行個體的個數function Person(name,age) {    this.name = name;    this.age = age;    Person.counter++; //沒建立一個執行個體,類變數counter加1};Person.whoIsOlder = function(p1,p2) { //類方法,判斷誰的年齡較大    if(p1.age > p2.age) {        return p1;    } else {        return p2;    }}var p1 = new Person("p1",18);var p2 = new Person("p2",22);alert("現在有 " + Person.counter + "個人");  //現在有2個人var p = Person.whoIsOlder(p1,p2);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  

 

function Circle(radius) {    this.radius = radius;    this.area = function() {        return 3.14 * this.radius * this.radius;    }}var c = new Circle(1);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  

 

function Circle(radius) {    this.radius = radius;}Circle.prototype.area = function() {        return 3.14 * this.radius * this.radius;    }var c = new Circle(1);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.   
  8. function PositionCircle(x,y,radius) { //定義類PositionCircle   
  9.     this.x = x;                    //屬性橫座標   
  10.     this.y = y;                    //屬性縱座標   
  11.     Circle.call(this,radius);      //調用父類的方法,相當於調用this.Circle(radius),設定PositionCircle類的   
  12.                                    //radius屬性   
  13. }   
  14. PositionCircle.prototype = new Circle(); //設定PositionCircle的父類為Circle類   
  15.   
  16. var pc = new PositionCircle(1,2,1);   
  17. alert(pc.area());  //3.14   
  18.                    //PositionCircle類的area方法繼承自Circle類,而Circle類的   
  19.                    //area方法又繼承自它的prototype屬性對應的prototype對象   
  20. alert(pc.radius); //1  PositionCircle類的radius屬性繼承自Circle類   
  21.   
  22. /*  
  23. 注意:在前面我們設定PositionCircle類的prototype屬性指向了一個Circle對象,  
  24. 因此pc的prototype屬性繼承了Circle對象的prototype屬性,而Circle對象的constructor屬  
  25. 性(即Circle對象對應的prototype對象的constructor屬性)是指向Circle的,所以此處彈出  
  26. 的是Circ.  
  27. */  
  28. alert(pc.constructor); //Circle       
  29.   
  30. /*為此,我們在設計好了類的繼承關係後,還要設定子類的constructor屬性,否則它會指向父類  
  31. 的constructor屬性  
  32. */  
  33. PositionCircle.prototype.constructor = PositionCircle   
  34. alert(pc.constructor);  //PositionCircle  

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.