2017-02-14 132 views
1

這裏有兩個回調函數:如何通過一個回調函數有多個可能的參數列表

function callback_a(){ 
    alert('a'); 
} 

function callback_b(p){ 
    alert('b says'+ p)' 
} 

如果我想使用callback_a

function test(callback){ 
    if(condition){ 
    callback(); 
    } 
} 

test(callback_a); 

但功能test並不適用於callback_b,所以如何實現一個通用函數,你可以通過多個可能的參數列表傳遞一些回調函數。

+0

爲什麼不t簡單地調用如下測試:'test(callback_b('what b have to say'))' – malarres

+1

@malarres它仍然會如果條件爲false,則執行'callback_b' – qslcna

+0

@malarres:**和**它會在'test'之前執行'callback_b' * first *。 –

回答

2

有一個叫做arguments的特殊對象,它在函數被調用時被創建。它是一個數組狀物體表示傳遞到一個函數的參數:

它可用於這樣的:

test(); 
    // no arguments passed, but it still gets created: 
    // arguments.length = 0 
    // arguments >> [] 

test(a); 
    // ONE argument passed: 
    // arguments.length = 1 
    // arguments >> [a] 

test(a,b,c,d); 
    // FOUR arguments passed: 
    // arguments.length = 4 
    // arguments >> [a,b,c,d] 

知道了這一點,可調用一回調與在傳遞的參數的其餘部分使用apply這樣父功能:

function test(callback) { 
    callback.apply(null, Array.prototype.slice.call(arguments, 1)); 
} 
// arguments passed into test are available in the function scope when 
// .slice is used here to only pass the portion of the arguments 
// array relevant to the callback (i.e. any arguments minus the 
// first argument which is the callback itself.) 
// 
// N.B. The arguments object isn't an array but an array like object so 
// .slice isn't available on it directly, hence .call was used here) 

可能是值得閱讀起來:

+0

這似乎沒有太多關聯的問題,問題是關於將不同的函數傳遞到具有不同形式參數列表的'test'中,答案是關於傳遞給'test',這個問題甚至開始回答這個問題了嗎?另外,最後的例子是將'callback'傳遞給自己,這似乎是一件很奇怪的事情,尤其是考慮到'callback_b'對參數做了什麼 –

+0

@ TJCrowder:OP發佈:_「如何實現一個可以傳遞一些回調函數的通用函數有多個可能的參數列表「_」。我讀到,他們如何去處理不同的回調,其參數列表各不相同,並仍然能夠將相關參數傳遞給回調函數。 – Pineda

+0

@ T.J。克羅德:同意,我舉的例子是奇怪,我沒有最初包括警告的第一個參數是回調,但我認爲這將是隱含的,如果OP理解推理我答案背後(因此在'test'處理argumetns或'callback'水平 – Pineda

0

可以傳遞參數,而調用回調

function test(callback){ 
 
    if(condition){ 
 
    callback(); 
 
    } 
 
    else if(other condition){ 
 
    callback("b"); 
 
    } 
 
} 
 

 
test(callback_b);

你可以寫你的回調函數一樣

function callback_a_b(){ 
 
    if(arguments.length){ 
 
    var arg = [].slice.call(arguments); 
 
    alert('b says'+ arg[0]) 
 
    } 
 
    else{ 
 
    alert('a'); 
 
    } 
 
    
 
}

+0

我想用這種方式使用函數'test',你可以通過'callback_a'和'callback_b'到它,它應該工作:) – qslcna

+0

但是,如果傳遞callback_a作爲回調函數。這正是OP希望得到答案的問題。 – Connum

+0

@qslcna查看已更新的答案 – ricky

0

您可以傳遞一個匿名函數作爲回調函數,該回調函數本身將返回您所需的具有參數的回調函數。

test(function() { return callback_b(' how are you'); }); 

看到,將首先使用callback_a這個工作片斷,然後callback_b(帶參數)作爲回調:

function callback_a(){ 
 
    alert('a'); 
 
} 
 

 
function callback_b(p){ 
 
    alert('b says'+ p); 
 
} 
 

 
function test(callback){ 
 
    if(true){ 
 
    callback(); 
 
    } 
 
} 
 

 
test(callback_a); 
 
test(function() { return callback_b(' how are you'); });

2

因此,如何實現一個共同的功能你可以傳遞一些回調函數和多個可能的參數列表。

基本上,你不知道。接收回調的函數負責回調接收的參數。當你調用Array#forEach,這是Array#forEach是決定你的回調得到什麼論據。同樣,String#replace定義了它將調用其回調函數的內容。

你的任務是說什麼test會做什麼,它會調用它的回調有。然後,它的使用test適當地寫自己的回調人的工作。例如:你可以記錄test作爲調用不帶參數的回調。如果主叫方希望使用callback_b,那麼它是由他們來處理callback_b需要一個參數的事實。有幾種方法,他們可以這樣做:

的可以在另一個函數把它包:

test(function() { 
    callback_b("appropriate value here"); 
}); 

...或使用Function#bind

test(callback_b.bind(null, "appropriate value here")); 

...但它他們問題, 不是你的。

備註:如果他們通過你callback_b並且你沒有任何參數地調用它,你將不會得到一個錯誤。 JavaScript允許使用比期望的參數更少的參數來調用函數,或者更多。函數如何處理,取決於函數的作者。

+0

我不確定它是否適合稱爲_callback_。實際上,我只是想在執行'callback_a'或'callback_b'之前通過'test'做出判斷,以確定它們是否應該執行。 – qslcna

+0

@qslcna:恐怕我不明白你的第一點。你正在通過'test'函數並調用它;這是一個教科書的回調。回想第二點,您可以通過查看其「長度」屬性來檢查您收到的函數的參數。這告訴你它接受了多少個形式參數,例如'function foo(a,b){}'具有'2'的'foo.length'。 (但它很複雜; ES2015的靜態參數和默認參數不顯示在函數的參數中) –

+0

第一點,我的意思是我不知道它是否適合說它是_callback_函數的一種 – qslcna

0

可以傳遞參數數組的test功能或使用ES6傳播OPER第二PARAM ator read more here

function test(callback, params){ 
    if(condition){ 
    if (params === undefined){ 
     callback(); 
    } else { 
     callback.apply(null, params); //params must be array 
     //ES6: callback(...params); 
    } 
    } 
} 

test(callback_a); 
test(callback_b, [" whatever"]); 
0

我剛纔在我的瀏覽器(ffox 51.0。1)以下工作:

function test(callback,other_args){if(condition){callback(other_args);}} 

結果:

  • 條件=真
  • 試驗(callback_a)
    • =>示出了具有 'A'
  • 警報
  • condition = false
  • 試驗(callback_a)
    • =>不顯示任何東西
  • 條件=真
  • 試驗(callback_b 「佩佩」)
    • =>示出了具有「B警報sayspepe」
  • 條件=假
  • 試驗(callback_b 「佩佩」)
    • =>不顯示任何
2

有三個選項:

  • 最簡單的方法是使用傳播運營商:

    function test(callback, ...callback_args) { 
        callback(...callback_args); 
    } 
    

    在這種情況下調用test函數callback_b會是這樣:

    test(callback_b,"b") 
    
  • 的第二種方式是使用arguments其範圍限定於任何功能在JavaScript:

    function test(callback) { 
        callback.apply(null, arguments.slice(1)); 
    } 
    

    test爲功能callback_b調用將是相同的:

    test(callback_b,"b") 
    
  • 另一種選擇是使用curried函數。在這種情況下,你應該定義b_callback像這樣(ES6語法):

    let callback_b = (p) =>() => void{ 
        alert('b says'+ p)' 
    } 
    

    或不ES6

    function callback_b(p) { 
        return function(){ 
         alert('b says'+ p)' 
        } 
    } 
    

    並調用它像這樣:

    test(callback_b("b")) 
    
相關問題