Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Created February 21, 2017 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XoseLluis/b8bea83ba4d1c3d52c6513e3a3a83fb1 to your computer and use it in GitHub Desktop.
Save XoseLluis/b8bea83ba4d1c3d52c6513e3a3a83fb1 to your computer and use it in GitHub Desktop.
function addMethodMissingCapabilityToClass(classConstructor, manageMissingItem){
let _proto = classConstructor.prototype;
classConstructor.prototype = new Proxy(_proto, {
get: function(target, key, receiver){
//console.log("get trap invoked");
if (key in target){
return target[key];
}
else{
//the problem here is that I can not know if they were asking for a method of for a data field
//so this makes sense for a missing method, but for missing properties it does not
return manageMissingItem(target, key);
}
}
});
}
class Person{
constructor(name){
this.name = name;
}
say(word){
return `${word}, I'm ${this.name}`;
}
}
class Employee extends Person{
constructor(name){
super(name);
}
doWork(wrk1, wrk2){
return `${this.name} has done some work: {wrk1} and {wrk2}`;
}
}
function testAddToClass(){
//my new "subclass"
function EmployeeWithMethodMissing(name){
// I can not use "super" here...
// //Employee.call(this); not allowed to call a constructor other than with new
let emp = new Employee(name);
Reflect.setPrototypeOf(emp, EmployeeWithMethodMissing.prototype);
return emp;
}
EmployeeWithMethodMissing.prototype = new Employee();
EmployeeWithMethodMissing.prototype.constructor = EmployeeWithMethodMissing;
addMethodMissingCapabilityToClass(EmployeeWithMethodMissing,
//manageMissingItem function
function(target, key){
if (key === "tell" || key === "speak"){
console.log(`method missing, but ${key} is synonymous with "say"`);
return function(...args){
console.log("calling the returned function with " + this.name);
return this.say(...args);
//be careful, here I can not use the trick of using "target" rather than "this" to avoid going through the proxy again in the next call, cause I'm proxying the prototype and hence target is the proto, not the object
// console.log("calling the returned function with " + target.prototype.constructor.name);
// return target.say(...args);
};
}
else{
return undefined;
}
}
);
let e1 = new EmployeeWithMethodMissing("Laurent");
console.log(e1.doWork("task1", "task2"));
console.log(e1.say("Hi"));
console.log(e1.tell("Hi Again"));
try{
console.log(e1.tttteeeelll("Hi Again"));
}
catch(ex){
console.error("exception: " + ex.message);
}
console.log(e1.missingProperty);
//instanceof works fine
console.log("e1 instanceof Employee: " + (e1 instanceof Employee).toString()); //true
console.log("e1 instanceof Person: " + (e1 instanceof Person).toString()); //true
console.log("e1 instanceof EmployeeWithMethodMissing: " + (e1 instanceof EmployeeWithMethodMissing).toString()); //true
console.log("ewmm1.constructor.name: " + e1.constructor.name);
}
testAddToClass();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment