ECMA5的getter/setter語法

 Sat, 16 Jan 2010 22:21:20 +0800

ECMA-262 Edition5在去年(2009)十二月通過成為新的javascript標準,最近看到一篇(其實就是node.js)blog文章 "ECMA 5/Mozilla Features Implemented in V8" 提到Chrome瀏覽器目前對於新標準的支援,其中有getter及setter,所以就來嘗試一下囉。

有興趣的話可以參閱ECMA-262 Edition5的11.1.5 Object Initialiser,以下用簡單的例子來看看怎麼使用:

<html>
<body>
</body>
</html>
<script type="text/javascript">
var obj = function(){
    var b = "hey";
    return {get a(){return b;}, set a(x){b=x;}};
}();
alert(obj.a);
obj.a = "ney";
alert(obj.a);
</script>
(這個例子簡單模仿javabean,但是因為scope的關係在setter裡面不可能有一個變數可以在getter取用,所以這裡用closure來把值用變數b保存)

簡單地說,在ECMA3的object initialiser語法之外,可以用類似函數的方式來宣告物件屬性。用 get 屬性名稱(){函數本體} 就會在取用這個物件的屬性時呼叫函數執行所返回的結果,用 set 屬性名稱(參數列表){函數本體} 就會在指派值給屬性時把值傳給函數本體來執行。

不過在getter/setter內使用本身的屬性名稱會有邏輯上的問題,或者可以說,下面這樣的作法是無效的:

var obj = {get a(){return this.a}, set a(x){this.a=x;}};
(這樣理論上會造成一個無窮迴圈)

但是可以存取其他屬性,例如:

<html>
<body>
</body>
</html>
<script type="text/javascript">
var obj = function(){
    var b = "hey";
    return {get a(){return b;}, set a(x){b=x;}, get b(){return this.a;}, set b(x){this.a=x;}};
}();
alert(obj.a);
obj.a = "ney";
alert(obj.a);
obj.b = "nei nei";
alert(obj.a);
alert(obj.b);
</script>

至於getter/setter能怎樣使用,則看大家的想像力了。