Я придумал способ, который позволит вам использовать псевдоключевое слово Super, изменив контекст выполнения (способ, который мне еще предстоит увидеть, представлен здесь). Недостаток, который я обнаружил, что меня не устраиваетэто вовсе не означает, что он не может добавить переменную «Super» к контексту выполнения метода, а вместо этого заменяет его на весь контекст выполнения, это означает, что любые частные методы, определенные с помощью метода, становятся недоступными ...
Этот методочень похож на представленный OP "eval hack", однако он не выполняет никакой обработки исходной строки функции, просто повторно объявляет функцию с использованием eval в текущем контексте выполнения.Делать это немного лучше, поскольку оба метода имеют один и тот же вышеупомянутый недостаток.
Очень простой метод:
function extend(child, parent){
var superify = function(/* Super */){
// Make MakeClass scope unavailable.
var child = undefined,
parent = undefined,
superify = null,
parentSuper = undefined,
oldProto = undefined,
keys = undefined,
i = undefined,
len = undefined;
// Make Super available to returned func.
var Super = arguments[0];
return function(/* func */){
/* This redefines the function with the current execution context.
* Meaning that when the returned function is called it will have all of the current scopes variables available to it, which right here is just "Super"
* This has the unfortunate side effect of ripping the old execution context away from the method meaning that no private methods that may have been defined in the original scope are available to it.
*/
return eval("("+ arguments[0] +")");
};
};
var parentSuper = superify(parent.prototype);
var oldProto = child.prototype;
var keys = Object.getOwnPropertyNames(oldProto);
child.prototype = Object.create(parent.prototype);
Object.defineProperty(child.prototype, "constructor", {enumerable: false, value: child});
for(var i = 0, len = keys.length; i<len; i++)
if("function" === typeof oldProto[keys[i]])
child.prototype[keys[i]] = parentSuper(oldProto[keys[i]]);
}
Пример создания класса
function P(){}
P.prototype.logSomething = function(){console.log("Bro.");};
function C(){}
C.prototype.logSomething = function(){console.log("Cool story"); Super.logSomething.call(this);}
extend(C, P);
var test = new C();
test.logSomething(); // "Cool story" "Bro."
Пример недостатка, упомянутого ранее.
(function(){
function privateMethod(){console.log("In a private method");}
function P(){};
window.C = function C(){};
C.prototype.privilagedMethod = function(){
// This throws an error because when we call extend on this class this function gets redefined in a new scope where privateMethod is not available.
privateMethod();
}
extend(C, P);
})()
var test = new C();
test.privilagedMethod(); // throws error
Также обратите внимание, что этот метод не "превосходит" дочерний конструктор, что означает, что Super не доступен для него.Я просто хотел объяснить концепцию, а не сделать рабочую библиотеку:)
Кроме того, я просто понял, что я выполнил все условия ОП!(Хотя действительно должно быть условие о контексте выполнения)