如何定义一个函数来产生调用函数的完全调用

时间:2018-02-02 19:02:48

标签: javascript arguments

我想定义一个可以从其他函数中调用的日志记录函数。日志记录功能应该打印调用函数的完整调用。例如:

function logger() {}

function F(obj1, obj2) {
    logger();
}
F('foo', {bar: 'baz'});   // console output: F('foo', {bar: 'baz'})

我已接近以下记录器:

function logger(args) {
    // Here the arguments objects holds the arguments passed to the
    // logger function, not the calling function.
    // We use it to get the calling function's name.
    let invocation = arguments.callee.caller.toString()
        .match(/function ([^\(]+)/)[1];

    // invocation === name of calling function

    // The arguments object from the calling function is passed
    // in as args in order to get the arguments passed with the 
    // calling function.
    let argArray = Array.from(args, function (obj) {
        return JSON.stringify(obj);
    });

    invocation += `(${argArray.join(', ')})`;
    console.log(invocation);  // Works as intended
}

这样可行,但我每次都必须将arguments参数传递给记录器函数:

function F(obj1, obj2) {
    logger(arguments);
}

有没有办法避免重复始终向记录器提供arguments参数?

2 个答案:

答案 0 :(得分:1)

你非常接近你回答:

function logger() {
    // Here the arguments objects holds the arguments passed to the
    // logger function, not the calling function.
    // We use it to get the calling function's name.
    let invocation = arguments.callee.caller.toString().match(/function ([^\(]+)/)[1];

    // invocation === name of calling function
    // The arguments object from the calling function is passed
    // in as args in order to get the arguments passed with the 
    // calling function.
    // Here how you can get the caller args - arguments.callee.caller.arguments
    let argArray = Array.from(arguments.callee.caller.arguments, 
        function (obj) {
            //Passed function can't be stringified, so by default they 
            //return empty string and you can just try to get the name or 
            //make a check if arg is a function object
            return JSON.stringify(obj) || obj.name;
        });

    invocation += `(${argArray.join(', ')})`;
    console.log(invocation);  // Works as intended
}

function F(obj1, obj2) {
    logger(arguments);
}

// console output: F('foo', {bar: 'baz'}, test);
F('foo', {bar: 'baz'}, function test() {});   

顺便说一下,收到通知,所有这些东西都不能在严格模式下工作,因为那里禁止使用任何“被调用者”方法。

答案 1 :(得分:0)

您可以使用功能currying。请参阅以下示例。

function multiplication(a, b) {

    return a*b;

}

var multiplesOfTwo = multiplication.bind(this, 2);  // function currying
console.log(multiplesOfTwo(3));
console.log(multiplesOfTwo(5));

被乘数始终为2.上述实现将避免在每次调用时传递2。