Created
February 21, 2017 19:15
-
-
Save XoseLluis/b8bea83ba4d1c3d52c6513e3a3a83fb1 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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); | |
} | |
} | |
}); | |
} |
This file contains hidden or 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
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