2009-12-17 31 views
4

我想在JavaScript中編寫一個幫助器方法。如果發送函數或函數引用,它的行爲應該是不同的。找出函數是匿名還是在對象中定義

我想喜歡用這樣的:

helper('div', function() { return false; }) 
helper('div', obj.fn) 

我想不通的是:如何幫助函數裏面分辨出兩者之間的區別?

我認爲這是由於的JavaScript首先計算obj.fn發送它之前。 我發現的唯一的解決方法是發送obj.fn作爲OBJ,即

helper('div', { fn: obj.fn }) 

然後我可以用typeof來區分兩者的區別。但我真的很喜歡某種方式讓它沒有額外的對象聲明。

+2

你有一個特定的原因,爲什麼你想分開兩個功能? – Boldewyn 2009-12-17 11:13:32

+3

「如果發送函數或函數的引用,它的行爲應該不同」 - 這是什麼意思?你如何定義「功能」和「功能參考」之間的區別?在你的第一個例子中,傳遞給helper的參數將是對函數的引用。 – 2009-12-17 11:55:47

+0

@Tim Down,這讓我感到困惑,但我認爲提問者認爲傳遞一個匿名函數是傳遞值並傳遞一個對象方法是傳遞通過引用,這當然是錯誤的,但它是許多js開發人員犯的錯誤。 – 2009-12-17 12:24:06

回答

0

您可以使用toString()找出如果函數是匿名的,假設它被聲明爲命名的功能,而不是分配給一個變量的匿名函數:

function jim() { var h = "hello"; } 
function jeff(func) 
{ 
    var fName; 
    var inFunc = func.toString(); 
    var rExp = /^function ([^\s]+) \(\)/; 
    if (fName = inFunc.match(rExp)) 
     fName = fName[1]; 

    alert(fName); 
} 

會給你函數的名稱(如果有的話)。

jeff(function() { blah(); }); // alert: null; 
jeff(function joe() { blah(); }); // alert: "joe"; 
jeff(jack); // "jack" if jack is function jack() { }, null if jack = function() {} 

我以前的編輯,你仍然可以指定命名的功能對象屬性使用命名功能提到了一個IE的怪癖而已,並沒有其他的瀏覽器存在,並且不再有效,在IE爲9版本然而表情:

var obj = { 
    fn: function namedFunction() { } 
}; 

這適用於所有瀏覽器,但IE 8,下不堅持它說的功能僅適用於通過自己的塊內這個名字的規範。

+0

我想'jack = function(){}'和'function jack(){}'是一樣的,或者我正在混合使用Scheme ... – Skilldrick 2009-12-17 11:19:46

+0

'function jack(){}'是一個已命名的函數,'jack = function(){}'是一個賦予變量的未命名函數。 – 2009-12-17 11:21:26

+0

我很想知道-1是什麼... – 2009-12-17 11:21:57

2

UPDATED *(AGAIN): 我認爲toString()方法可能是你在這裏的唯一方法。但它不會以不同方式處理匿名對象的引用。

此代碼表明:

function acceptparam(fn){ 

      console.log("fn.constructor = " + fn.constructor); 
      console.log("typeof fn = " + typeof fn); 
      console.log("fn toString " + fn.toString()); 

      console.log("fn.prototype = " + fn.prototype); 
      console.log("fn.prototype.constructor = " + fn.prototype.constructor); 
      console.log("this[0] = " + this[0]); 
      console.log("---"); 

     } 

     function empty(){ 
      return ; 
     } 

     var x = { 
      y : function(){return;} 
     } 

     acceptparam(empty); 
     acceptparam(function(){return;}); 
     acceptparam(x.y); 

很有趣的問題,沒有實現自己的解決方案,我不認爲你可以做到這一點,這篇文章有助於解釋爲什麼。它關於父母的子女關係只是一種方式。

http://codingforums.com/showthread.php?t=134855

+0

你是對的toString ...仔細看看控制檯輸出:'fn toString函數empty()'vs.'fn toString function()' – Skilldrick 2009-12-17 11:21:34

+0

這就是Andy E的答案:P – Skilldrick 2009-12-17 11:22:26

+3

那不是他要問的問題因爲thoguh,這是我最初出錯的地方! fredrik正在要求匿名函數和帶有子函數的對象之間的區別,該函數不起作用。 – Lewis 2009-12-17 11:30:07

1

我想我會添加另一個替代答案,主要是因爲我不想添加到湯是我的其他答案,但也因爲它沒有順利與stackoverflow選民沒有離開建設性的意見;-)

作爲一種替代你想做什麼,你可以第三個參數添加到輔助函數:

function helper (tagName, fn, method) 
{ 
    if (method) 
     fn = fn[method]; 

    //- Do rest of helper function here 
} 
//- Now if we pass an object method to helper function we can identify it properly 
helper('div', obj, "fn"); // method is obj.fn 
helper('div', function() { blah(); }); // Still works fine 

僅僅是一個建議和作品,以及甚至比你目前的解決方案更好。

+0

謝謝。但實際上這是我第一次嘗試。但我想盡可能簡單。但現在一直在搞這個。而且它看起來像我必須指定保存該函數的obj,因爲我希望fn被觸發,它應該放在正確的位置。因此,this關鍵字被稱爲obj。 – fredrik 2009-12-17 13:32:56

相關問題