Skip to content

Instantly share code, notes, and snippets.

@mapserver2007
Created May 19, 2011 09:18
Show Gist options
  • Save mapserver2007/980454 to your computer and use it in GitHub Desktop.
Save mapserver2007/980454 to your computer and use it in GitHub Desktop.
プロトタイプベースOOP試作その2.2
var Telephone = Module.create({
getPhoneName: function() {
return "kurodenwa";
},
getType: function() {
return "old type";
},
telephone: function() {}
});
var Feature = Module.create({
getPhoneName: function() {
return "garake-";
},
feature: function() {}
});
var Iphone = Module.create({
getPhoneName: function() {
return "iphone";
},
iphone: function() {}
});
var Android = Module.create({
getPhoneName: function() {
return "android";
}
});
var o1 = Iphone.mix(Feature).mix(Telephone); // Mix-in
//alert(o1.getPhoneName()); // iphone
//alert(o1.parent().getPhoneName()); // garake-
//alert(o1.parent().parent().getPhoneName()); // kurodenwa
//alert(o1.getType()); // old type
var o2 = Iphone.mix(Feature, Telephone); // 多重継承
//alert(o2.parent().getPhoneName()); // garake-
//alert(o2.parent().parent().getPhoneName()); // kurodenwa
//alert(o2.getType()); // old type
var o3 = Android.mix(o1); // Mix-in済みオブジェクトをMix-in
alert(o3.getPhoneName()); // android
alert(o3.parent().getPhoneName()); // iphone
alert(o1.getPhoneName()); // iphone
var Module = {};
Module.create = function(base) {
var isIE = function() { return !!document.attachEvent; };
var clone = function(o) {
var c = {};
for (var prop in o) {
c[prop] = o[prop];
}
if (!isIE()) {
c.__proto__ = o.__proto__;
}
return c;
};
if (isIE()) {
base.mix = function() {
// 親が継承済みの場合を考慮するため親の階層を辿る
var parents = [];
for (var i = 0, len = arguments.length; i < len; i++) {
for (var parent = clone(arguments[i]);;) {
parents.push(parent);
if (parent.hasOwnProperty("parent")) {
parent = parent.parent();
}
else {
break;
}
}
}
// 子が継承済みの場合を考慮するため子の階層を辿る
var children = [];
for (var c = clone(this);;) {
children.push(c);
if (c.hasOwnProperty("parent")) {
c = c.parent();
}
else {
break;
}
}
// 自分の祖先が持っているメソッドを子供に受け継がせる
var ancestors = children.concat(parents);
for (var k = ancestors.length - 1; k > 0; k--) {
var parentNo = k,
childNo = parentNo - 1;
var c = ancestors[childNo],
p = ancestors[parentNo];
ancestors[childNo].parent = (function(p) {
return function() {
return p;
};
})(ancestors[parentNo]);
for (var prop in p) if (!c.hasOwnProperty(prop)) {
c[prop] = p[prop];
}
}
return ancestors[0];
};
}
else {
base.parent = function() { return this.__proto__; };
base.mix = function() {
var parents = arguments,
child = clone(this);
for (var i = 0, len = parents.length; i < len; i++) {
var parent = clone(parents[i]),
depth = 0;
for (var _c = child;;) {
_c = _c.__proto__;
if (_c !== null) {
depth++;
}
else {
break;
}
}
var propList = ["child"];
for (var d = 1; d <= depth; d++) {
propList[d] = "__proto__";
};
eval(propList.join(".") + " = parent");
}
return child;
};
}
return base;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment