2015-05-11 41 views
2

我嘗試了一些以下的事情,它滿足了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

這幾乎可以肯定是X/Y的問題:你想幹什麼X,你認爲你可以進行Y做到這一點,但你在做Y時遇到困難,所以詢問如何去做。但是如果我們知道X是什麼,我們幾乎可以肯定會提出比Y更好的方法。 –

回答

3

如何從主叫原型

retrive類名不能*,一對夫婦的原因:

  1. 功能沒有name財產。 They will in ES6,但他們還沒有。 (你可以指定一個屬性B的名稱,雖然)。

  2. 雖然你可以得到這對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以告訴你它的運行版本:

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>

+0

@Crowder:謝謝你的回答。在這裏,我的要求是跟蹤API函數的使用情況,爲了實現它,我遵循這種方式,如果有更好的改變方式,請給我建議。此外,我無法更改已有框架 – KGopi

+0

@ user3620283:我已添加到答案的末尾。但從根本上說:有這樣的圖書館,我會使用一個,而不是試圖重塑它。 :-)(通過新的'Proxy'對象,ES6將使事情變得更加強大。) –

+0

@Crowder:再次感謝代碼片段。這裏的問題是函數A.ao將被從很多地方(類+不同的文件)調用。甚至從不同的功能(差異func名稱)。所以答案可能無法解決我的問題,儘管我喜歡這種方法。 – KGopi

0

您可以在返回其類型的對象中包含一個方法。另一種選擇是使用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)調用所需的方法來提供當前調用者的上下文。

+0

但是調用者是'B.bo',而不是'A'。 –

+0

@ T.J.Crowder我已經更新了答案。有一件事是缺少的是應用與當前調用者的上下文調用的方法。 –