2017-08-16 48 views
1
// 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函数来说明一种名为“猴子补丁”的练习。我真搞不清楚该行的性质原函数被调用:JS中的执行上下文感到困惑

var result = original.apply(this, arguments); // Invoke original. 

据我了解,原来的函数调用也无apply()帮助下写的,因为thisarg是this,也就是说执行上下文保持不变:original对象。

第二个困惑点是地狱arguments参数apply()来自哪里?是的,我知道它是在每个函数调用中生成的一个对象,用于访问函数参数 - 但此行位于不带任何参数的匿名函数内。我没有任何线索,并且很感激任何暗示。

预先感谢您!

+0

@dayuloli那个本地执行环境会是什么?为了再次引用我的书,“函数使用范围链在执行定义时生效”,这并不意味着执行环境是匿名函数吗? –

+0

如果执行上下文是anynomous函数的执行上下文,那么这是否意味着'arguments'对象是空的(因为该函数没有任何参数)?那会是什么意思?我不想使用原始函数会收到的参数吗? –

+0

“* thisarg是'this',这就是说执行上下文保持不变:'original' object *” - 否'original'是应该调用的函数(方法)引用,它不是上下文。而且你不知道'this'上下文是否是'o'(方法被覆盖的对象) - 它可以是任何东西。因此,我们使用'this'。 – Bergi

回答

2

您的第一个问题:为什么需要apply

如果直接在匿名函数调用originalthisoriginal是一定要参考globalundefined在严格模式下)。另一方面,匿名函数声明为o的一种方法,所以如果您调用o.m(),this内部的匿名函数应该参考o。因为它保留了语义,所以需要传递ooriginal

除了绑定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的值只能在调用函数时确定为,它根本不是固定的。

​​

arguments被分配一个值时被调用x,它是动态的。