初學JavaScript的時候有人會認為JavaScript不是一門面向對象的語言,因為JS是沒有類的概念的,但是這並不代表JavaScript沒有對象的存在,而且JavaScript也提供了其它的方式來解決面向對象的問題。所以JavaScript也是一門面向對象的語言。 面向對象僅僅是一個概念或者 ...
初學JavaScript的時候有人會認為JavaScript不是一門面向對象的語言,因為JS是沒有類的概念的,但是這並不代表JavaScript沒有對象的存在,而且JavaScript也提供了其它的方式來解決面向對象的問題。所以JavaScript也是一門面向對象的語言。
面向對象僅僅是一個概念或者編程思想而已,它不應該依賴於某個語言存在。比如 PHP採用面向對象思想構造其語言,它實現了類、繼承、派生、多態、介面等機制。但是這些機制,只是實現面向對象編程的一種手段,而非必須。換言之,一門語言可以根據其自身特性選擇合適的方式來實現面向對象。因而先入為主地接受了"類"這個面向對象實現方式。
JavaScript不同於其它語言,它是通過原型(prototype)的方式來實現面向對象編程的,也就是說對象(object)是依靠構造器(constructor)利用原型(prototype)構造出來的,而有時也稱它為偽類。
下麵說一下麵向對象的實現方式,為了好理解,我們借鑒其它語言中類和對象的思想來簡單分析一下:
一:最簡單的面向對象(即使用JSON方式來聲明)
定義一個偽類:
var Ren = { name:"張三", //相當於成員變數 sex:"男", //相當於成員變數 age:18, //相當於成員變數 say:function(){ //相當於成員方法 alert("講話"); } };
調用類裡面的成員:
Ren.say();
通過上面的例子可以看出來,該類裡面的成員相當於其它語言裡面的靜態成員,通過類名調用。
這種方式基本可以滿足開發的需求,但是相對於其它語言來說沒有實現封裝、繼承和多態,所以代碼的重用性比較差。
二:使用原型的方式(函數構造器)
定義一個類:
function Ren(){ var name="張三"; //私有的成員變數 var sex ="男"; //私有的成員變數 this.PublicName="zhangsan", //公有的成員變數 this.setName = function(_name){ //成員方法 name=_name; } this.getName = function(){ //成員方法 return name; } }
造對象並且調用對象的成員:
var r = new Ren(); r.getName();
在創建對象的時候,會運行類似於這樣的代碼,使用構造器來創建對象:
this.prototype = {constructor: this}
函數的prototype的屬性的值被作為原型對象來克隆出新對象。
雖然使用new運算符調用函數看起來像是使用模板實例化的方式來創建對象,但本質還是以原型對象來克隆出新對象,目前我們看它像是一個類,但還有一點就是每new Ren(),不但屬性產生副本,方法也會產生副本。
如果不想讓方法產生複本,它提供了prototype這個屬性,即原型。所有實例都會共用它裡面的屬性和方法。
可以在定義對象的時候:把屬性放到定義里,而把對象的方法放到原型里!
如下:
function Ren(name, age) { this.name = "張三"; this.age = 18; }; Ren.prototype.say = function(){ //方法放在原型裡面 alert("hello"); };
調用該成員方法:
var r = new Ren(); r.say();
以上兩種方式都可以實現JavaScript中的面向對象,實際上每種語言的面向對象思想都是一致的,只是方法有所不同而已,在JavaScript這門強大的語言裡面依然是有面向對象存在的只是我們學習了其它語言的面向對象之後,有種先入為主的感覺,對JavaScript的面向對象產生疑惑,所以一定謹記面向對象是一種思想,不是一種方法。