// Replace the method named m of the object o with a version that logs
// messages before and after invoking the original method.
function trace(o, m) {
// Remember original method in the closure
var original = o[m];
// Define the new method
o[m] = function() {
// Log message
console.log(new Date(), "Entering:", m);
// Invoke original
var result = original.apply(this, arguments);
// Log message
console.log(new Date(), "Exiting:", m);
return result;
};
}
您好!上面给出的代码示例来自我的编码书。它试图用JavaScript中的apply
函数来说明一种称为“猴子修补”的实践。我真的很困惑调用原始函数的行的性质:
var result = original.apply(this, arguments); // Invoke original.
据我所知,原始函数的调用也可以在apply()
的帮助下编写,因为thisarg是this
,也就是说执行上下文保持不变: original
对象。
第二点混淆是arguments
的{{1}}论证来自哪里?是的,我知道它是在每个函数调用中生成的对象,用于访问函数参数 - 但是这一行是在没有任何参数的匿名函数内部。我没有任何线索,我很感激任何提示。
提前谢谢!
答案 0 :(得分:2)
您的第一个问题:为什么需要apply
?
如果您直接在匿名函数中调用original
,this
内的original
肯定会在严格模式下引用global
(undefined
)。另一方面,匿名函数被声明为o
的方法,因此如果您调用o.m()
,匿名函数内的this
应引用o
。需要将o
传递给original
,因为它保留了语义。
除了绑定this
之外,apply
还可以将参数数组转换为单个参数。
function toBeCalled(x,y){
console.log('x is: '+x+" y is:"+y)
}
function x (){
toBeCalled(arguments)
toBeCalled.apply(this,arguments)
}
x('aa','bb','vv')
//x is: [object Arguments] y is:undefined
//x is: aa y is:bb
看到区别?
第二个问题:arguments
来自哪里?
在JavaScript中,arguments
是函数范围内的内置变量。 arguments
的值只能在调用函数时确定 ,它根本不固定。
function x (){
console.log(arguments)
}
x('aa','bb','vv')
x("ff","dd")
x(1123)
arguments
在调用x
时分配了一个值,它是动态的。