2014-01-09 26 views
2

考慮此代碼:獲取函數名稱,如印刷在Chrome控制檯

var o = {}; 
o.f = function(){}; 
new o.f; 

鉻打印o.f {}到控制檯。你知道如何調用這個零件嗎?更重要的是,有沒有辦法在不使用控制檯的情況下得到這個結果?我想從函數本身提取方法的名稱,也就是說,沒有任何附加信息。

我已經知道如何在這種情況下獲得的名稱:

function f(){} 
f+'' // "function f(){}" 

不過,這並不表現在上述情況相同的方式。


以下內容大多是從comments複製。

我想知道是否有一個「技術」字來談論這個o.f模式,比如說「命名空間」,「標識符」或「功能路徑」。然後,我想知道是否有方法從網頁中的加載腳本中檢索此信息。下面的問題可能會幫助你理解我的目標,在第一個代碼塊與我的想法非常接近之後的段落:Does Chrome retain each object's constructor?

也許我應該提到,我最初的目標是在運行時生成一個文檔:/在某些情況下,反射API可能會有幫助。更確切地說,我正在尋找一種方法,將方法的名稱包含在函數的反編譯形式中。看:

function Class(){} 
Class.prototype.method = function(){}; 

Class.prototype.method + ''給出function(){}。我想注入方法的名稱來得到這個結果:function method(){}

問題是我沒有任何有關我當前正在序列化哪些函數的信息,因爲操作發生在用戶單擊鏈接時。我知道我可以輕鬆地將名稱存儲在某個地方,例如將數據綁定到錨元素,這對我來說很明顯,我只是好奇地想知道是否有辦法像Chrome一樣檢索這些數據。

+0

你需要什麼? – zerkms

+0

有沒有辦法與js(據我所知) –

+0

可能重複的[我可以得到當前正在運行的函數在JavaScript中的名稱?](http://stackoverflow.com/questions/1013239/can-i-get - 當前運行的函數在JavaScript中) – Quentin

回答

1

嗯,這似乎是一個再簡單不過的問題,只要所有這些結構的命名雲:

o.f = function(){}; 

是一種常見的說法,包括更常見的表情。 o.f只是訪問對象屬性的兩種方法之一,通常稱爲點符號。雖然我相信JS中的點(。)並不是真的被看作是一個運算符,但我將它稱作是今後的運算符成員。
接下來我們有着名的賦值運算符,它將左側的操作數賦給左側(對象o的成員,名爲f)。
右邊的表達式(需要被評估爲單數值)是一個函數定義,它不是單獨使用語句,而是用作表達式。鑑於這個事實,我們將這種功能用作函數表達式

在這種特殊情況下,函數沒有名字,它是一個匿名函數。在內部,大多數 - 如果不是所有的引擎 - 都會給它一個名字,但這不是JS應該知道或者真正關心的東西。就JS而言,這個函數沒有名字,只能通過o.f訪問。如果你這樣調用這個函數:o.f(),它的上下文將是對象o的上下文,從而有效地使這個函數像一個方法一樣工作。
所以基本上你的陳述是這樣的:「指定並創建如果需要的o成員f,這是一個匿名函數。」函數本身沒有名字。

考慮一下:

var o = {f: function(){console.log('I am a function');}}; 
var foobar = o.f; 
foobar();//logs I am a function 

所以稱名稱的功能o.ff並不總是適用的。其他變量或屬性可以引用相同的功能。這是因爲函數是第一類對象,它們可以被返回,傳遞給任何東西並從中分配。

答案,那麼,是爲使用這2種方法之一:

您可以通過添加一個名稱改變函數表達式,把它變成一個命名函數表達式

f.o = function newName(){}; 

newName名稱除了舊版本的IE之外,在函數範圍之外不可用。這是ECMA規範see the details here所要求的。無論如何,現在我們可以檢查:

var func = function func(){console.log(func);}; 
//same name: 
func();//logs function func(){} 
var foobar = func; 
foobar();//logs function func(){} 
func = 123;//<-- no longer function 
foobar();//still function func(){}//func is still accessible 
var hidden = (function() 
{ 
    return function named() 
    { 
     console.log(named);//access name 
    }; 
}()); 
hidden();//logs function named(){} 
console.log(named);//undefined -> not visible outside the function itself 

函數的名稱被限制在它自己的範圍內。

使用正則表達式,這是稍微哈克,並在兩個變量/屬性引用相同的函數對象不拾取:

o = {f: function(){console.log('I am a function');}}; 
for (var pName in o) 
{//probably add o.hasOwnProperty(pName) check to be safe 
    if (o[pName] instanceof Function) 
    { 
     console.log(o.f.toString().replace(
      /^function\s*\(/, 
      'function o.'+pName+'(') 
     ); 
    } 
} 

這stringifies(給function(){/*body*/})功能,並與function <propertyName>(取代function ( 。如果該功能已有自己的名稱,則該名稱不會被替換。

+0

所以沒有Chrome的祕密地方:)無論如何,所有這一切非常有趣。謝謝! – leaf

1

一般來說,這在Javascript或編程中並不常見。

但是,function確實有一個屬性名稱 - 請參閱Function.name。 但在您的代碼中o.f是一個無名稱函數。

var o = {}; 
o.f = function(){}; //function(){} creates a nameless function. 

可以前()

var o = {}; 
o.f = function f(){}; //function f(){} creates a function with the name f 

然後

o.f.name == 'f' 

注意定義一個名字:這個功能在IE瀏覽器的支持,而不是EMCA的規範