簡體   English   中英

如何獲得調用者函數的類名

[英]How to get caller function class name

我在下面嘗試了一些方法,它滿足了80%的需求,盡管不足以使用。

// Different file
function A(){}

A.prototype.ao = function(){
    // Here I want ot know the fucntion caller class name, for that I used
    arguments.callee.caller.prototype; // It retuens B.bo {} (object)
}

// Different file
function B(){}
B.prototype.bo = function(){
    var a = new A();
    a.ao();
}

如何從調用程序原型中檢索類名稱,因為它是對象類型。

如果我們能夠獲得調用者函數的上下文,我會有所幫助。

如何從調用程序原型中檢索類名稱

您不能*,原因有兩個:

  1. 函數沒有name屬性。 他們將在ES6中使用 ,但還沒有。 (不過,您可以使用名稱將屬性分配給B

  2. 盡管您可以獲得對B.prototype.bo上的函數的B.prototype.bo ,但是沒有從那里回到B鏈接。 鏈接是單向的。 (尤其是因為同一功能可能在多個對象上。)

請注意, 強烈建議不要使用arguments.callee ,在嚴格模式下則不允許使用, 尤其不建議使用caller 幾乎總是有一種更好的方法來做您想做的事情。


*在某些引擎上,您可能可以從調用堆棧中找出來,例如:

A.prototype.ao = function(){
    try {
        throw new Error();
    }
    catch (e) {
        // Examine e.stack here
    }
};

您將依賴於特定於平台的命名等。

但是,再一次,幾乎肯定有一個比試圖知道誰在打給您更好的選擇。


發表您的評論:

在這里,我的要求是跟蹤API函數的使用情況,為了實現它,我正在按照這種方式進行操作……而且,我無法更改現有框架。

您可能會但沒有意識到,因為JavaScript是如此強大。 :-)

例如:一旦將任何創建B框架加載到頁面上,下面的代碼就會將B.prototype上的每個函數B.prototype為一個告訴您正在運行的版本:

function wrapFunctions(name, proto) {
    Object.keys(proto).forEach(function(key) {
        var original = proto[key];
        if (typeof original === "function") {
            proto[key] = function() {
                var rv;
                starting(name, key);    // <=== Your function to tracking the start of a call
                rv = original.apply(this, arguments);
                stopping(name, key);    // <=== Your function tracking the end of the call
                return rv;
            };
        }
    });
}
wrapFunctions("B", B.prototype);

那就是“樂器”的開始。 但是請注意,那里有解決此問題的適當庫。

現場示例

 // The framework function B() {} B.prototype.f1 = function() { snippet.log("Original functionality for f1"); }; B.prototype.f2 = function() { snippet.log("Original functionality for f2"); }; B.prototype.f3 = function() { snippet.log("Original functionality for f3 -- calling f2"); this.f2(); snippet.log("Original functionality for f3 -- done calling f2"); }; // Let's use f1 and f2 before we wrap them snippet.log("Before wrapping:"); var b1 = new B(); b1.f1(); b1.f2(); b1.f3(); // Now your code runs and wraps them wrapFunctions("B", B.prototype); // Now let's use f1 and f2 again snippet.log("After wrapping:"); var b2 = new B(); b2.f1(); b2.f2(); b1.f3(); // Our function to track that a call started function starting(ctor, name) { snippet.log(ctor + "#" + name + ": Started"); } // Our function to track that a call stopped function stopping(ctor, name) { snippet.log(ctor + "#" + name + ": Stopped"); } // Our function to wrap things function wrapFunctions(name, proto) { Object.keys(proto).forEach(function(key) { var original = proto[key]; if (typeof original === "function") { proto[key] = function() { var rv; starting(name, key); // <=== Your function to tracking the start of a call rv = original.apply(this, arguments); stopping(name, key); // <=== Your function tracking the end of the call return rv; }; } }); } 
 <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script> 

您可以在對象中包含一個返回其類型的方法。 另一種選擇是使用instanceof並檢查所有可能的類型。

function A() {
    this.getType = function () {
        return "A";
    }
}

A.prototype.ao = function() {
    // Here I want ot know the fucntion caller class name, for that I used
    var type = this.getType();
    args.callee.caller.prototype; // It retuens B.bo {} (object)
}

function B(){
    this.getType = function () {
        return "B";
    }
}

B.prototype.bo = function(){
    var a = new A();
    a.ao.apply(this);
}

在這里,您還必須在所有繼承的類型中重新定義getType並返回正確的類型。 您還需要使用apply(this)調用所需的方法以提供當前調用方的上下文。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM