分享

Javascript 沒有 OO?是你不知道 OO 是什麼吧

 quasiceo 2017-10-23

Javascript 沒有 OO?是你不知道 OO 是什麼吧

February 18, 2013 西杰 編程, 0

在 Programming 圈子混久了,常常聽到人家說 Javascript 是一隻沒有 OO 的語言,又或者說 Javascript 的 OO 很弱,我想,這大概是因為大家都習慣了用 Class 來實作 OO,認為這個世界上有 Class 才算是寫 OO。要探討這個問題,先要想想 OO 到底是什麼。本文除了分享我對 Javascript OO 的看法外,亦會介紹一下在 Javascript 中編寫 Object 的幾種方法。

維基給 OO 下的定義:

 concepts as “objects” that have data fields (attributes that describe the object) and associated procedures known as methods

如果只是根據這個標準的話,那很明顯 Javascript 可以輕鬆過關,Javascript 最基本最簡單的 Object 寫法就可以有 data fields 和 procedures。

好吧,那嚴謹一點,一般 OO 語言有什麼特徵?我想主要有三:InheritancePolymorphismEncapsulation,來看看 Javascript 如何做到這幾項。

Inheritance,在 Javascript 中如何繼承一個 class 呢?答案是使用 Object 裏的 prototype 屬性!Javascript 是一種 prototype-based language,prototype-based language 的特徵是透過複製現有的 object 來重用代碼,注意,是 object 而不是 class,這就是 prototype-based OO 跟 class-based OO 最大的分別了。以下是一個繼承 object 的示範:

var base = {
    test: function (){
        $("#msg").html($("#msg").html() + "test<br/>");
    }
};

base.test2 = function (){
    $("#msg").html($("#msg").html() + "test2<br/>");
};

function sub(){
}
sub.prototype = base;

var subObj = new sub();
subObj.test();
subObj.test2();

這有什麼好處呢?就是令 Javascript 更加動態,可以在 runtime 時加上 function,不用在 compile time 就定死一個 class 有什麼行為。

Polymorphism,因為 Javascript 的動態,它天生就是多態的,在使用一個 object 的 method 時,Javascript 會根據你最後一次的改變來決定使用哪個 method。

function Shape(){
}
Shape.prototype.sayHello = function (){
    //to be implemented
};

function Rect(){
}
Rect.prototype = new Shape();
Rect.prototype.sayHello = function (){
    $("#msg").html($("#msg").html() + "I am Rect<br/>");
};

function Circle(){
}
Circle.prototype = new Shape();
Circle.prototype.sayHello = function (){
    $("#msg").html($("#msg").html() + "I am Circle<br/>");
};

var shapes = [new Rect(), new Circle(), new Rect()];
for (var i = 0, l = shapes.length; i < l; i++){
    shapes[i].sayHello();
}

Encapsulation,其核心思想是只“顯示”必需的東西。在 class-based OO 我們是透過 public private 等關鍵字來控制一個 method 的存取權,那在 Javascript 中我們如何做到呢?其實 Javascript 是一個擁有 first-class function 的語言,所謂 first-class function 的意思就是這隻語言容許 function 作為一般變數般處理,例如你可以把 function 當成 argument 般傳到另一個 function 使用,亦可以當成變數般儲存。憑著這個特異功能,我們就可以編寫 private method 了。

function cls(){
    var privateMethod = function (){
        $("#msg").html($("#msg").html() + "calling private method<br/>");
    }

    return {
        publicMethod: function (){
            $("#msg").html($("#msg").html() + "calling public method<br/>");

            privateMethod();
        }
    }
}

var obj = new cls();
obj.publicMethod();

Javascript 其實是一隻擁有完整 OO 的語言,除了因為它的變數類型都是 object 之外,亦因為他擁有上述三大 OO 特性:Inheritance、Polymorphism 及 Encapsulation。因此,下次再有人說 Javascript 不是一隻 OO 語言的話,你就可以大大聲跟他說:是你不懂得 Javascript  是什麼,是你不懂得何謂 OO!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多