我想实现多级继承,支持通过在被扩展对象上执行的扩展方法实现的多态性(而不是通过外部实用程序或函数 - 从被扩展对象的角度来看)。
tl; jsfiddle 博士在这里:http: //jsfiddle.net/arzo/VLkF7/
我想要的是?
var MyObj = {name: 'object', toString: function() {return this.name;}};
MyObj.extend = function(objectToBeMerged) {
var objs=[this, objectToBeMerged],
newobj={},
obj;
for(var i in objs) {
for(var k in (obj=objs[i]) ) if (obj.hasOwnProperty(k)) newobj[k]=obj[k];
}
return newobj;
}
console.assert(MyObj.extend, 'ERROR: this should pass');
var ActionObj = MyObj.extend({name: 'action abstract object', exec: 'implemtation', undo: 'implementation of opposite action here'});
var DragNDrop = ActionObj.extend({name: 'drag&drop action', exec: function(){console.log('did d&d');}})
//unfortunately following assert will not get through, because MyObj.extend cannot iterate over ActionObj properties
if(DragNDrop.toString) console.info('MyObj.extend iterated over MyObj\'s properties')
console.assert(DragNDrop.undo, 'but MyObj.extend did not iterate over ActionObj properties, undo action is missing in this object:', DragNDrop)
;
上面的代码有什么问题?如果这是常规的,例如 C++ 继承,则 DragNDrop 将具有undo方法,但它没有,因为var objs=[this, objectToBeMerged]仅将 this 评估为MyObj,但我希望将其评估为扩展的任何对象被执行(所以在执行 ActionObj.extend 的情况下,我想在函数扩展中将关键字this评估为ActionObj,而不是MyObj)
此问题的解决方案可能是使用 jQuery.extend 的 _.extend,如下所示:
//add here code in previous quote in this post...
MyUtils = {}
MyUtils.extend = function(objectToBeMerged, parent) {
var objs=[parent || this, objectToBeMerged],
newobj={},
obj;
for(var i in objs) {
for(var k in (obj=objs[i]) ) if (obj.hasOwnProperty(k)) newobj[k]=obj[k];
}
return newobj;
}
console.assert(MyObj && ActionObj, 'are you sure you have added code from previous block?');
var DnDAction=MyUtils.extend({name: 'drag&drop action', exec: function(){console.log('did d&d');}},ActionObj);
if (DnDAction.undo) console.info('using MyUtils.extend works fine and .undo is defined as expected in', DnDAction)
;
但上述解决方案需要使用外部工具 -MyUtils
在这种情况下,这不是真正的多态解决方案。
您知道如何强制 MyObj.extend 在运行时评估(而不是何时定义评估)this
表达式上进行迭代吗?