Я хотел бы реализовать многоуровневое наследование, поддерживающее полиморфизм, реализованный метод расширения, выполняемый на расширяемом объекте (не по внешней утилите или функции - с точки зрения расширяемого объекта).Многоуровневый полиморфизм в javascript, полиморфный Object.extend
Т.Л., др 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 бы отменить метод, но это не так, потому что вар OBJS = [это, objectToBeMerged] оценивает это только MyObj, но хотелось бы, чтобы он оценивали на любой объект, на котором простираются выполняется (так в случае выполнения ActionObj.extend, я хотел бы иметь ключевое слово это в функция расширения оценивается в ActionObj, не MyObj)
Решение этой проблемы может использовать _.exten d из jQuery.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
выражения?