现在我有一个对象,例如这支笔。
该类的原型包含一系列功能和其他属性。
var Pen = function(){
this.inkColor = 'red';
this.write = function(text){
document.write(text);
}
this.refill = function(){
console.log('refilling');
}
this.getInkColor = function(){
return this.inkColor;
}
};
var pen = new Pen();
pen.write(pen.getInkColor() + ': Hello');
有没有避免修改Pen类的方法,而是改变它具有的每个函数的行为,例如在实际函数调用之前打印日志?
this.write = function(text){
// do something first
document.write(text);
}
this.refill = function(){
// do something first
console.log('refilling');
}
this.getInkColor = function(){
// do something first
return this.inkColor;
}
答案 0 :(得分:4)
您可以将笔包在Proxy中并定义适当的处理程序。
var Pen = function(){
this.inkColor = 'red';
this.write = function(text){
document.write(text);
}
this.refill = function(){
console.log('refilling');
}
this.getInkColor = function(){
return this.inkColor;
}
};
var handler = {
get: function(target, name) {
return name in target ? function (...args) {console.log('Hello World'); return target[name](args)} : undefined;
}
};
var pen = new Pen();
var p = new Proxy(pen, handler);
p.write(p.getInkColor() + ': Hello');
答案 1 :(得分:2)
您可以用调用原始函数的包装程序替换函数,也可以执行其他操作。例如:
Object.keys(pen).forEach(name => {
const originalFunction = pen[name];
if (typeof originalFunction === "function") {
pen[name] = function(...args) {
console.log(name, args);
return originalFunction.apply(this, args);
};
}
});
这将用首先执行pen
然后调用原始函数的包装程序替换console.log
上的所有功能(仅是其自身的功能,而不是其继承的功能)。
实时示例:
var Pen = function(){
this.inkColor = 'red';
this.write = function(text){
// used console.log instead of document.write
console.log(text);
}
this.refill = function(){
console.log('refilling');
}
this.getInkColor = function(){
return this.inkColor;
}
};
var pen = new Pen();
Object.keys(pen).forEach(name => {
const originalFunction = pen[name];
if (typeof originalFunction === "function") {
pen[name] = function(...args) {
console.log(name, args);
return originalFunction.apply(this, args);
};
}
});
pen.write(pen.getInkColor() + ': Hello');
您可以对其进行调整,以处理从原型继承的或仅从Pen.prototype
继承的函数(目前Pen.prototype
上没有任何东西),等等。
答案 2 :(得分:2)
您可以编写一个返回另一个函数的函数:
function doSomethingFirst(somethingToDoFirstFn, thingToDoAfterFn) {
return function() {
somethingToDoFirstFn.apply(null, arguments);
thingToDoAfterFn.apply(null, arguments);
}
}
var Pen = function(){
// code
this.refill = doSomethingFirst(function(){
console.log('somethingFirst');
}, function() {
console.log('refilling');
})
// code
};