2015-05-03 80 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

相关问题