一張圖解釋javascript原型、原型鏈,對象、原型對象,模擬類,模擬繼承。

 

 

 

 

 

                                                            圖1 關係圖解javascript

 

 

__proto__(雙橫線):javascript中對象內置的隱藏屬性,相似指針,指向其引用對象的原型對象。java

prototype:函數對象的一個屬性,也相似於一個指針,指向其原型對象。函數

Point{}:Point的原型對象。測試

Point:Point的構造函數。this

 

如圖1,定義一個函數 Point(),其中Poin對象增長p1屬性,Point原型對象增長一個sum方法。p1,p2爲Point()的實例化對象,name1,name2分別爲p1,p2的屬性。代碼以下:prototype

function Point(){指針

      var p1 = "測試點";對象

}blog

Point.prototype.sum = function (){繼承

   var sum = function(){

       return 1+2;

     }     

}

var P1 = new Point();

var P2 = new Poin();

P1.name1 = "點1";

P2.name2 = "點2";

 

P1擁有的屬性和方法:sum方法,Name1屬性。

P2擁有的屬性和方法:sum方法,Name2屬性。

javascript搜索一個對象的屬性和方法,先默認搜索自身的屬性和方法,若是自身沒搜索到,再經過__proto__屬性找到其引用對象的原型對象,如此經過__proto__一層層往下找,最終__proto__的指針指向null;

諸如:P1-->Point{}-->Object{}-->null 經過__proto__造成的一條鏈路,這條鏈路即是原型鏈。

 

經過上述代碼模擬了一個Point類 ,其中p1爲Point的私有屬性,sum爲Point的公共方法。經過new Point()創建的爲Point的實例化對象,擁有Point的全部公共屬性和方法。

若想獲取 Point的私有屬性,能夠進行以下改造:

function Point(){

      var p1 = "測試點";

      this.getP1 = function (){

            return p1;

     }

}

這樣,就能對Point實現封裝,提供讀取p1屬性的方法。

 

有了Point類,也能進行封裝了,那如何實現繼承?

由關係圖可知,經過 Animal.prototype = new Point(); 就能夠實現繼承,Animal繼承了Point,擁有Point的全部公共屬性和方法。A1爲Animal的實例化對象,則A1 不只擁有Animal的全部公共屬性和方法,並且擁有Point的全部公共屬性和方法。代碼以下:

function Animal(){

          var add1 = function (){ return "add1";};

          this.add2 = function (){ return "add2";};

}

 Animal.prototype.run = "run";   //此行不是代碼內容,只是爲了測試更改原型對象後此屬性是否還存在。

Animal.prototype = new Point();

var A1 = new Animal();

 

此時A1擁有的屬性和方法爲:add2方法,sum方法。add1做爲Animal的私有方法沒法獲取,run則屬性Animal之前的原型對象的屬性,也沒法獲取,sum做爲Animal繼承的方法,可以獲取。而A1可以擁有add2方法則是由於在Javascript中,this指向函數執行時的當前對象該關鍵字在Javascript中和執行環境,而非聲明環境有關。 this關鍵字雖然是在定義Animal的時候生成的,可是在new Animal()的時候才執行,所以add2得以存在。

 

 

PS:本身畫的圖和寫的內容,非轉載,剛畢業的菜鳥,若是我理解的有不對的地方歡迎你們指正。

另:原型鏈當然強大,可是由於javascript是動態語言,經過原型鏈甚至能修改繼承的父類的屬性和方法,還能給父類增長讀寫方法。關於如何防止別人隨意篡改父類的屬性,還請大牛們指點一二。

相關文章
相關標籤/搜索