對JavaScript中原型的理解

從純粹的面向對象思想(Java思想)向Javascript語言面向對象思想的轉化,經歷沉痛而慘烈。Javascript中對象和類的概念轉化悄然不動聲色,讓人迷糊。有時候,對Java理解得越清楚,對Javascript理解起來就越費勁。尤其對Javascript的原型對象的理解頗費功夫。

按照定義,每個javascript對象都有一個原型對象(簡稱原型),這個原型是由該對象的構造函數所定義(javascript自動創建的),並且對象繼承原型的所有屬性和方法(函數),比如 一個String對象 的原型爲 String.prototype ,如果我們想要給String類添加方法,可以這樣做(比如添加常用的trim()方法):

js 代碼

String.prototype.trim = function (){   
  return this.replace(/(^\s*)|(\s*$)/g, "");   
}  

這個特性是相當令人驚訝的,因爲這破壞了封裝性,就好像在Java中你可以對String類直接進行修改一樣。function() 可以當作數據來給左操作數賦值(而不僅僅是當作動作),也跟Java非常地不同。

對於Javascript內部類都可以這麼改,對於自定義類當然可以這麼改,如:

function Circle(x,y,r){   
  this.x = x;   
  this.y = y;   
  this.r = r;   
  //this.prototype = null ;     /*這句代碼可以看作是隱含存在的,因爲javascript 中“類”的定義和函數的定義結構上沒有差異,所以可以說,所有函數都隱藏有這樣一個屬性。*/   
}   

然後,我們給原型加一個得到面積的方法:

Circle.prototype.area = function(){   
  return this.r * this.r * 3.14159 ;   
}  

可以這樣使用:


var circ = new Circle(0,0,2) ;   
alert(circ.area()) ;  

當然,我們也可以在類中很輕鬆的定義我們想要實現的方法,如,還是上面那個求圓面積:

function Circle(x,y,r){   
  this.x = x;   
  this.y = y;    
  this.r = r ;   
  this.area = function (){   
    return this.r * this.r * 3.14159 ;    
  }   
}   
//調用:
var circ = new Circle(0,0,2) ;   
alert(circ.area()) ;   

兩者的調用代碼完全一樣,那爲什麼要使用原型呢?我感覺主要是爲了解決對內部類型的繼承問題,也就是說當你無法修改String的構造函數而想要讓所有String實例都具有某一方法的時候,你可以用這個prototype;或者說,你用這個prototype來模擬實現String類的子類,達到對父類進行擴展的目的。

 

參考:

JavaScript權威指南(第四版)





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章