読者です 読者をやめる 読者になる 読者になる

野次馬エンジニア道

野次馬な気持ちでプログラミングをあれこれと綴ります

JavaScriptでオブジェクト指向 (4) - ECMAScript 5の関数で

以前に一度まとめたが、下記を読んで興味がわいたので久しぶりにJavaScriptを。

オブジェクト指向JavaScriptの原則

オブジェクト指向JavaScriptの原則

この本のもう一つのテーマはECMAScript 5。

現在の主流であるECMAScript 3の範囲をカバーしつつ、ECMAScript 5で追加になったオブジェクトやオブジェクトプロパティ関連の関数を用いてオブジェクト指向を実現する方法を簡潔に解説してくれる良本*1

気になった箇所をまとめてみる。

準備

Object.definePropertyを使ったコンストラクタ

function Foo() {
    Object.defineProperty(this, "val", { 
        get : function() {
            return val;
        },
        set : function(newVal) {
            val = newVal;
        },
        enumerable : true,
        configurable: true
    });
    this.showValue = function() {
        console.log(this.val);
    };
}
  • Object.defineProperty()は引数を3つ取る
    • プロパティを持つオブジェクト
    • プロパティの名前
    • プロパティディスクリプタ
      • ここでは、get/setのアクセサプロパティ、enumerable - 列挙可能か、configurable - 変更可能か

Object.create()を使ったオブジェクト生成

var a = {foo:"bar"}; // は
var a = Object.create(Object.prototype, {
    foo: {
        configurable: true,
        enumerable: true,
        value : "bar",
        writable: true
    }
}); // と同じ。

オブジェクトリテラルによるプロトタイプ設定

前回も出たconstructorが正しくない問題のため、明示的にconstructorをセットしていることに注目

function Foo(val) {
    this.val = val;
}
Foo.prototype = {
    constructor: Foo,
    showValue: function() {
        console.log(this.val);
    }
};
var bar = new Foo("test");

bar instanceof Foo // true
bar.construrctor === Foo //true
bar.construrctor === Object //false

Object.create()を使った継承

以上をまとめると継承が下記のように記述できる。

SubClass.prototype = Object.create(BaseClass.prototype, {
    constructor: {
        configurable: true,
        enumerable: true,
        value : "bar",
        writable: true
    }
});

*1:訳者の注釈も豊富。またstrictモード時の動作にも言及がありとにかく長く参照できそう

*2: ブラウザによっては、__proto__ で知られる。ECMAScript6 で標準化される予定