2015-05-03 82 views
3

我的html包含兩個相互重疊的表單,一個用作添加表單,一個用作編輯表單。我使用jQuery來顯示和使用下面的代碼隱藏:爲什麼你必須用匿名函數包裝回調?

var editForm = $("#edit-form"); 
var addForm = $("#add-form"); 

var showEditForm = function() { 
    editForm.fadeIn(function() { 
     addForm.fadeOut(); 
    }); 
}; 
var showAddForm = function() { 
    editForm.fadeOut(function() { 
     addForm.fadeIn(); 
    }); 
}; 

我想使代碼更緊湊,所以我直接做這樣的設置​​呼叫的​​回調:

var showEditForm = function() { 
    editForm.fadeIn(addForm.fadeOut); 
}; 
var showAddForm = function() { 
    editForm.fadeOut(addForm.fadeIn); 
}; 

但是這產生以下錯誤Uncaught TypeError: Failed to execute 'animate' on 'Element': Valid arities are: [1], but 4 arguments provided.但爲什麼不工作?

+0

您必須提供一個函數,以便高階函數fadeout可以觸發它。這個答案的範圍可以從monad到syntax – raam86

回答

1

我懷疑的問題是,addForm.fadeOut被調用的參數的糟糕的組合,當其傳遞給fadeIn功能(反之亦然)。

這個陷阱的典型例子似乎是:

["0", "1", "2", "3"].map(function(i) {return parseInt(i);}) 

此,按預期工作,因此給予[1,2,3,4]。你可能會認爲你可以縮短這一點,就像你上面所做的那樣,並且寫出

["0", "1", "2", "3"].map(parseInt); 

不幸的是;這評估爲[0, NaN, NaN, NaN]。問題是,.map調用任何函數提供了三個參數:值,索引和數組本身,parseInt最多接受兩個參數:值,但也解析基數/基數(例如基數2解析字符串爲二進制),所以真正發生的本質:

[ 
    parseInt("0", 0), //0, radix is ignored 
    parseInt("1", 1), //NaN, what is base 1? 
    parseInt("2", 2), //NaN, 2 isn't valid binary 
    parseInt("3", 3) //NaN, 3 isn't valid ternary/base-3 
] 

我懷疑,基於錯誤信息,同樣的事情是怎麼回事。函數的「arity」是傳遞給它的參數的數量,所以這裏的錯誤信息表示提供了4個參數,當只有一個參數被預期時。

通常,對於帶有可選參數的函數,在將它們直接傳遞給其他函數之前需要小心,否則您將無法控制將使用哪些參數進行調用。

+0

這確實會產生錯誤。使用'addForm.fadeOut(function(){editForm.fadeIn.apply(this,arguments);});'拋出完全相同的錯誤 –

8

這是因爲調用函數作爲對象的屬性是一種特殊的語法,它以對象作爲上下文來調用函數。

當你調用這樣的功能:

obj.func(); 

然後this將裏面的功能,以obj參考。

如果你得到的參考函數,然後調用它:

var f = obj.func; 
f(); 

然後this將是全球範圍內引用,即window對象。

通過使用editForm.fadeIn(addForm.fadeOut);您可以參考addForm.fadeOut併發送到fadeIn方法。它不再與對象關聯,因此將使用全局上下文而不是對象作爲上下文來調用它。

可以使用proxy方法的功能與對象關聯,這樣它會用正確的上下文中調用:

var showEditForm = function() { 
    editForm.fadeIn($.proxy(addForm.fadeOut, addForm)); 
}; 
var showAddForm = function() { 
    editForm.fadeOut($.proxy(addForm.fadeIn, addForm)); 
}; 
2

小提琴:http://jsfiddle.net/jmj8tLfm/

addForm.fadeInaddForm.fadeOut被稱爲無指定在撥打addForm.fadeIn()時通常會傳遞的this上下文。嘗試.bind()適當-ing this變量如下:

var showEditForm = function() { 
    editForm.fadeIn(addForm.fadeOut.bind(addForm)); 
}; 
var showAddForm = function() { 
    editForm.fadeOut(addForm.fadeIn.bind(addForm)); 
}; 
+0

['bind' method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)並不是全部支持的瀏覽器,所以我推薦['proxy'方法](http://api.jquery.com/jQuery.proxy/)。 – Guffa

相關問題