对 JS 中的执行上下文感到困惑

Confused about execution context in JS

// 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 对象。

第二个困惑点是 argumentsapply() 的争论从何而来?是的,我知道它是在每次函数调用时生成的对象,用于访问函数参数——但这一行是在一个没有任何参数的匿名函数中。我没有任何线索,非常感谢任何提示。

提前致谢!

您的第一个问题:为什么 apply 是必要的?

如果在匿名函数中直接调用originaloriginal里面的this肯定会引用globalundefined在严格模式下) .另一方面,匿名函数被声明为 o 的方法,因此如果您调用为 o.m(),则匿名函数内部的 this 应该引用 o。需要将 o 传递给 original,因为它保留了语义。

除了绑定 thisapply 还可以将参数数组转换为单个参数。

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时赋值的,是动态的。