简体   繁体   English

对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;
  };
}

Hello! 你好! The code example given above is from my coding book. 上面给出的代码示例来自我的编码书。 It tries to illustrate a practice called “monkey-patching” using the apply function in JavaScript. 它试图使用JavaScript中的apply函数来说明一种称为“ monkey-patching”的做法。 I'm really confused about the nature of the line where the original function is invoked: 我真的对调用原始函数的行的性质感到困惑:

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

As far as I understand, the call to the original function could also be written without the help of apply() , since the thisarg is this , which is to say that the execution context remains unchanged: the original object. 据我了解,对原始函数的调用也可以在没有apply()的帮助下编写,因为thisarg是this ,也就是说执行上下文保持不变: original对象。

The second point of confusion is where the hell the arguments argument for apply() comes from? 第二个困惑点是apply()arguments参数从何而来? Yes, I know that it is an object generated at every function invocation that is used to access the function arguments - but this line is inside an anonymous function without any arguments. 是的,我知道这是在每次函数调用时生成的对象,用于访问函数参数-但此行位于没有任何参数的匿名函数内部。 I don't have a clue and am grateful for any hint. 我没有任何线索,不胜感激。

Thank you in advance! 先感谢您!

Your first question: Why is apply necessary? 您的第一个问题:为什么必须apply

If you invoke original directly in the anonymous function, this inside original is sure to refer to global ( undefined in strict mode). 如果直接在匿名函数中调用original ,则this original内部一定会引用global (在严格模式下undefined )。 The anonymous function, on the other hand, is declared as a method of o , so if you invoke as om() , this inside the anonymous function should refer to o . 匿名函数,在另一方面,被声明为的方法o ,所以如果你调用为om() this匿名函数内部应该参考o Passing o to original is desired because it preserved the semantic. 希望将o传递给original ,因为它保留了语义。

In addition to binding this , apply can also convert an array of arguments to individual parameters. 除了绑定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

See the difference? 看到不同?

Second question: Where is arguments from? 第二个问题: arguments来自哪里?

In JavaScript, arguments is a built-in variable within the scope of a function. 在JavaScript中, arguments是函数范围内的内置变量。 The value of arguments can only be determined when the function is invoked , it is not fixed at all. 仅在调用函数时才能确定arguments的值,而根本不固定。

function x (){
    console.log(arguments)
}

x('aa','bb','vv')
x("ff","dd")
x(1123)

arguments is assigned a value when x is invoked, it is dynamic. 调用xarguments分配了一个值,它是动态的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM