Extend
Extend.js は、オブジェクトに関数やプロパティを追加する関数を提供します。
- Extend は defineProperty を使い、まとめて追加します
- Extend.define は defineProperty を使い、一つずつ追加します
- Extend.mixin は defineProperty を使わずに、まとめて追加します
Extend.js の使用例は、 ES.js を参照してください。
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(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(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
});