天天看點

Javascript進階(8)---OOP

面對對象程式設計(OOP)

  • OOP定義

  面對對象程式設計(Object-oriented programming ,OOP),是一種程式設計範型,同時也是一種程式開發的方法。對象指的是類的執行個體。他将對象作為程式作用的基本單元,将程式和資料封裝其中,以提高程式的複用性。

                                                ---維基百科

  • OOP特點(相信大家都已爛熟于心)
    • 繼承  
    • 封裝  
    • 多态  
    • 抽象  
  • 對象執行個體化下的原型鍊
    • 任意聲明一個函數foo,其prototype屬性是一個object
      • Javascript進階(8)---OOP
    • 繼續測試JavaScript的内置構造器Number(),發現其prototype屬性仍是一個object
      • Javascript進階(8)---OOP
    • 舉例說明
      1 function Foo(){
      2   this.x = "x" ;
      3 }
      4 Foo.prototype.y="y";
      5 var foo1 = new Foo();
      6 console.log(foo1.x);   // x
      7 console.log(foo1.y);   // y      
      首先明确幾點:
      • prototype與__proto__不是一回事,prototype是一個JS對象,而__proto__是一個(幾乎)所有對象都有的一個屬性。
      • prototype是函數對象上預設的對象屬性(因為他是一個object)
      • __proto__是對象上的原型,通常指向其構造器的prototype屬性
      • 第2行的 this 在第 5 行使用new關鍵字建立對象的時候,這個this指向的是一個原型(即__proto__屬性)為Fun的prototype的一個空對象,然後通過this.x="x" 給這個空對象賦予屬性。不難看出這裡的this就是指向新生成的foo1對象,使用this.x挂載的屬性也将直接挂載在foo1對象上。
      • 在使用 new 進行建立對象執行個體的時候,prototype會被用作 new 出來這些對象的原型
      • 結構表示如圖
        Javascript進階(8)---OOP
    • 使用new建立對象執行個體之後,動态修改prototype的影響
      • 修改已經存在的prototype上的屬性 ,會直接對已經建立的執行個體造成影響                                                                           
        Javascript進階(8)---OOP
      • 直接修改prototype對象本身,不會對已經建立的執行個體造成影響
        Foo.prototype = {  } ;  //直接将prototype對象設定為一個空對象,這算是對prototype屬性的自身的直接修改      
        Javascript進階(8)---OOP
      • 無論使用上述哪種方法,修改過prototype屬性後,再使用new建立的執行個體,都會受到此次修改的影響
            

OOP實作繼承

1 function Person(name,age){
 2   this.name = name ;
 3   this.age = age;
 4 }
 5 
 6 Person.prototype.sayHi = function(){
 7   console.log("我的名字是:"+this.name+"我今年"+this.age+"歲。");
 8 }
 9 Person.prototype.LEGS_NUM = 2;
10 Person.prototype.ARMS_NUM = 2 ;
11 Person.prototype.walk=function(){
12   console.log(this.name + "會走路.....");
13 }
14 function Student(name,age,className){
15 Person.call(this,name,age);
16 this.className = className;
17 }
18 
19 
20 Student.prototype = Object.create(Person.prototype);   //建立一個空對象,并且這個對象的原型指向傳入的參數
21 Student.prototype.constructor = Student;         //手動将剛才建立的對象的construct指向Student,若不修改則指向Person
22 
23 
24 //定義Student類自己的方法sayHi
25 Student.prototype.sayHi = function (){            
26     console.log("我的名字是:"+this.name+"我是"+this.className+"班的學生。");  
27 }
28 //定義Student類自己的方法goto_school
29 Student.prototype.goto_school=function(subject){
30   console.log(this.name + "每天要去上"+subject+"課");
31 }

      
//測試
var Jay = new Student("Jay",37,"三年二班");   
 Jay.sayHi();                    //我的名字是:Jay我今年37歲。
 console.log(Jay.LEGS_NUM);            //2
 Jay.walk();                    //Jay會走路.....
 Jay.goto_school("數學");            //Jay每天要去上數學課      
  •  (25行)sayHi方法綁定在Student的prototype上,每當Student執行個體通路sayHi方法時候,先會在對象本身上找有沒有這個方法,發現沒有。然後在Student中找到了,則不會繼續原型鍊向上查找,與Java中覆寫父類方法類似
  • 在函數對象内使用this參數接收的變量,使用new執行個體化的時候,會作為新建立的對象的直接屬性。例如例子中的,name、age、className屬性。
  • (20行)實作繼承的時候,必須把父類(Person)和子類(Student)的prototype指向的對象分開來,因為子類在添加自己的屬性和方法的時候就不會影響到父類的一些屬性和方法。
  • 例子中原型鍊繼承結構如下
    • Javascript進階(8)---OOP
    • 從結構圖中不難發現,Student.prototype是使用Object.create()方法建立的(20行),是以他的原型(__proto__屬性)指向的是Person.prototype。
    • 對象的prototype的__proto__屬性一般都指向原型鍊頂端的Object.prototype。             
      Javascript進階(8)---OOP
                                                         

特别注意

上述例子中的__proto__屬性在chrome浏覽器中測試有效,在其他環境中,請使用Object提供的方法Object.getPrototypeOf(目标對象)的方法擷取對象的原型。                              
Javascript進階(8)---OOP

(本文歸納自慕課網大BOSN的課程http://www.imooc.com/video/7054,加入了些許個人了解,若侵權私信告知)

轉載于:https://www.cnblogs.com/HXW-from-DJTU/p/5974822.html