Skip to content
uupaa edited this page Apr 8, 2014 · 6 revisions

Extend.js は、オブジェクトに関数やプロパティを追加する関数を提供します。

  • Extend は defineProperty を使い、まとめて追加します
  • Extend.define は defineProperty を使い、一つずつ追加します
  • Extend.mixin は defineProperty を使わずに、まとめて追加します

Extend.js の使用例は、 ES.js を参照してください。

Extend

Extend(base:Global/Object/Function, extendTree:ExtendTreeObject, override:Boolean = false):void は、 extendTree に指定された階層状のオブジェクトを base に追加します。
追加は、Extend_define を使って行います。

override に true を指定すると、既存の値を上書きします。

function Extend(base,       // @arg Global/Object/Function: base object.
                extendTree, // @arg ExtendTreeObject: { "Object": { key: value, ... }, ... }
                override) { // @arg Boolean(= false): true is override.
                            // @help: Extend
//{@assert
    _if(!Valid.type(extendTree, "Object"),     "Extend(,extendTree)");
    _if(!Valid.type(override, "Boolean/omit"), "Extend(,,override)");
//}@assert

    _extend(base, extendTree, override);
}

function _extend(base, extendTree, override) {
    for (var klass in extendTree) { // "Object", "Array", "String", ...
        if ( !(klass in base) ) {
            base[klass] = {};
        }

        for (var prop in extendTree[klass]) { // "isArray", "prototype", ...
            if (prop === "prototype") {
                if ( !(prop in base[klass]) ) {
                    base[klass][prop] = {};
                }
                for (var key in extendTree[klass][prop]) {
                    Extend_define(base[klass][prop], key, extendTree[klass][prop][key], override);
                }
            } else {
                Extend_define(base[klass], prop, extendTree[klass][prop], override);
            }
        }
    }
}
Extend(global, {
    "Object": {
        "keys":     Object_keys,
        "freeze":   Object_freeze
    }
});

Extend.define

Extend.define(base:Global/Object/Function, key:String, value:Any, override:Boolean = false):void は、 defineProperty(base, key, { value: value, configurable: true, enumerable: false, writable: true }) を行います。 追加したプロパティや関数は、再設定可能, for-in ループで列挙不能, 書き換え可能な状態になります。

defineProperty をサポートしていない環境では、base[key] = value; を使って追加します(フォールバックします)。

override に true を指定すると、既存の値を上書きします。

複数のオブジェクトを追加する場合は、Extend を利用してください。

function Extend_define(base,       // @arg Global/Object/Function:
                       key,        // @arg String:
                       value,      // @arg Any:
                       override) { // @arg Boolean(= false):
                                   // @help: Extend.define
                                   // @desc: Object.defineProperty wrapper
//{@assert
    _if(!Valid.type(key, "String"),            "Extend.define(,key)");
    _if(!Valid.type(override, "Boolean/omit"), "Extend.define(,,,override)");
//}@assert

    var defineProperty = Object["defineProperty"] || polyfill_defineProperty;

    if ( override || !(key in base) ) {
        defineProperty(base, key, {
            "configurable": true, // false is immutable
            "enumerable": false,  // false is invisible(for in loop)
            "writable": true,     // false is read-only
            "value": value
        });
    }
}
Extend.define(Object, "keys", Object_keys);

Extend.mixin

Extend.mixin(base:Global/Object/Function, extend:Object, override:Boolean = false):base は、base に extend を追加します。
追加は、 base[key] = value; の形で行います。

override に true を指定すると、既存の値を上書きします。

function Extend_mixin(base,       // @arg Global/Object/Function: base object
                      extend,     // @arg Object: Object
                      override) { // @arg Boolean(= false):
                                  // @ret Object/Function:
                                  // @help: Extend.mixin
                                  // @desc: Mixin object.
//{@assert
    _if(!Valid.type(extend, "Object"), "Extend.mixin(,extend)");
    _if(!Valid.type(override, "Boolean/omit"), "Extend.mixin(,,override)");
//}@assert

    override = override || false;

    for (var key in extend) {
        if (override || !(key in base)) {
            base[key] = extend[key];
        }
    }
    return base;
}
var base = { a: 1, b: 2 };
var extra = { c: 3 };
var result = Extend.mixin(base, extra);

console.log(result); // { a: 1, b: 2, c: 3 }
// 既存のオブジェクトにプロパティや関数を追加する場合は、Extend.mixin を使わずに、
// Extend.define を使って下さい。

Extend.mixin(Object, {
  "keys": Object_keys
});
Clone this wiki locally