如何从自己的实现中引用一个函数?

Orr*_*oni 5 javascript

我正在开发一个由许多对象和函数(对象方法)组成的javascript应用程序.我希望能够在应用程序的生命周期中记录许多事件.我的问题是在记录器内部我想知道哪个函数调用了日志条目,所以我可以将这些数据与日志消息一起保存.这意味着每个函数都需要能够以某种方式引用自身,因此我可以将该引用传递给记录器.我正在使用javascript严格模式,因此arguments.callee不允许在函数内部使用.

这是一个可以运行的非常简化的代码示例.alert为了简单起见,我只是在这里使用而不是我的记录器.

(function(){
"use strict";

window.myObject = {
    id : 'myObject',
    myFunc : function(){
        alert(this.id); // myObject
        alert(this.myFunc.id); // myFunc - I don't want to do this. I want something generic for all functions under any object
        alert('???') // myFunc
        alert(arguments.callee.id); // Will throw an error because arguments.callee in not allowed in strict mode
    }
}
myObject.myFunc.id = 'myFunc';

myObject.myFunc();
})();
Run Code Online (Sandbox Code Playgroud)
  1. 在第一个警报 - this相关myObject和不相关myFunc
  2. 在第二个I警报中 - 我通过其名称引用了该函数,我不想这样做,因为我正在寻找一种从它自己的实现中引用函数的通用方法.
  3. 第三个提醒 - 为您的想法开放.
  4. 第四个警报 - 如果我不这样做会有效"use stict";.我想保持严格的模式,因为它提供了更好的性能,并构成了良好的编码实践.

任何输入将不胜感激.

如果你不熟悉"严格模式",这是一个很好的读取它的地方: JavaScript严格模式

Sky*_*kyd 4

这是一种非常hacky的方法:

(function(){
    "use strict";
    window.myObject = {
        id: 'myObject',
        myFunc: function () {
            // need this if to circumvent 'use strict' since funcId doesn't exist yet
            if (typeof funcId != 'undefined') 
                alert(funcId);
        },
        myFunc2: function () {
            // need this if to circumvent 'use strict' since funcId doesn't exist yet
            if (typeof funcId != 'undefined') 
                alert(funcId);
        }
    }
    // We're going to programatically find the name of each function and 'inject' that name
    // as the variable 'funcId' into each function by re-writing that function in a wrapper
    for (var i in window.myObject) {
        var func = window.myObject[i];
        if (typeof func === 'function') {
            window.myObject[i] = Function('var funcId = "' + i + '"; return (' + window.myObject[i] + ')()');
        }
    }

    window.myObject.myFunc();
    window.myObject.myFunc2();
})();
Run Code Online (Sandbox Code Playgroud)

本质上,我们在找到函数的名称后,通过从字符串重新编译每个函数来规避“use strict”声明。为此,我们在每个函数周围创建一个包装器,该包装器声明一个等于目标函数名称的字符串变量“funcId”,以便该变量现在通过闭包暴露给内部函数。

呃,这不是最好的做事方式,但它确实有效。 或者,您可以简单地从内部调用非严格函数:

(function(){
    "use strict";

    window.myObject = {
        id: 'myObject',
        myFunc: function () {
            alert(getFuncName())
        },
        myFunc2: function () {
            alert(getFuncName());
        }
    }
})();

// non-strict function here
function getFuncName(){
    return arguments.callee.caller.id; // Just fyi, IE doesn't have id var I think...so you gotta parse toString or something
}
Run Code Online (Sandbox Code Playgroud)

希望有帮助。