Created
May 19, 2011 09:18
-
-
Save mapserver2007/980454 to your computer and use it in GitHub Desktop.
プロトタイプベースOOP試作その2.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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