javascript - 通过函数调用 JavaScript 获取对象调用者名称

标签 javascript

我正在编写一段代码,以便轻松地将错误日志保存在对象中以进行调试。

我想要实现的是从调用它的函数中获取对象名称,如下所示:

var MainObject = {
    test : function() {
        return MainObject.test.caller;
        // When called from MainObject.testcaller,
        // it should return MainObject.testcaller.
    },

    testcaller : function() {
       return MainObject.test(); // Should return MainObject.testcaller, Returns own function code.
    },

    anothercaller : function() {
       return MainObject.test(); // Should return MainObject.anothercaller, Returns own function code.
    }
}

但是,当我运行此代码时,它会从 MainObject.testcaller 返回函数代码。

JSFiddle example

有什么办法可以做到这一点吗?

更新

查看 Rhumborl 的答案后,我发现通过另一个函数分配值会导致它指向函数名称,而不指向对象本身。

代码:

(function (name, func) {
    MainObject[name] = func;
})('invalid', function() {
    return MainObject.test("blah"); 
}); 

// This now points at invalid() rather than MainObject.invalid()

Updated fiddle

最佳答案

有一个非标准caller property返回调用者函数的函数,但是这是一个指向函数对象的指针,并且不会告诉您它作为方法被调用的对象或对象的名称。您可以通过 arguments.callee 获取该函数的引用.

还有过时的 arguments.caller ,但不要使用它。它还提供对调用函数的引用(如果支持)。

一旦获得了调用函数的引用(如果有的话),就会遇到解析其名称的问题。鉴于函数是对象,并且对象可以由多个属性和变量引用,因此具有特定名称的函数的概念是冲积的。

但是,如果您知道该函数是某个对象的属性,则可以迭代该对象自己的可枚举属性来找出它是哪一个。

但这似乎是一件相当奇怪的事情。你到底想做什么?您可能正在尝试解决一个可以通过更强大和更简单的方式解决的问题。

编辑

您可以使用上面针对OP中的情况描述的方法以非常有限的方式做您想做的事情,但是它不是健壮的或通用的解决方案:

var mainObject = {
    test : function() {
      var obj = this;
      var caller = arguments.callee.caller;
      var global = (function(){return this}());
      var fnName, objName;

      for (var p in global) {
        if (global[p] === obj) {
          objName = p;
        }
      }

      for (var f in obj) {
        if (obj[f] === caller) {
          fnName = f;
        }
      }

      return objName + '.' + fnName;
    },

    testcaller : function() {
       return mainObject.test();
    },

    anothercaller : function() {
       return mainObject.test();
    }
}


console.log(mainObject.testcaller());    // mainObject.testcaller
console.log(mainObject.anothercaller()); // mainObject.anothercaller

但它很脆:

var a = mainObject.anothercaller;
console.log(a()); // mainObject.anothercaller    

var b = {
  foo : mainObject.anothercaller
}

console.log(b.foo()); // mainObject.anothercaller

哎呀。

关于javascript - 通过函数调用 JavaScript 获取对象调用者名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26885825/

相关文章:

javascript - 使用 Webpack 在 devtools 中调试

javascript - 在 React Redux 应用程序中,我在哪里从服务器获取初始数据?

javascript - 通过带有神秘逗号的堆算法进行排列

javascript - 将 UTF-8 BOM 添加到字符串/Blob

javascript - 将鼠标悬停在段落上

javascript - Owl Carousel 根本不工作

javascript - 迭代具有动态类名的元素时,JQuery .each 循环不起作用

javascript - 鼠标悬停时堆栈图中的淡入淡出栏

javascript - 支持网络 worker 的 iPhone 浏览器?

javascript - 如何在 JavaScript 中实现 DOM 数据绑定(bind)