为什么必须使用匿名函数包装回调?

mmm*_*mmm 4 javascript jquery callback fadeout fadein

我的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();
    });
};
Run Code Online (Sandbox Code Playgroud)

我想让代码更紧凑,所以我通过这样做fadeOut()直接在fadeOut()回调上设置调用:

var showEditForm = function() {
    editForm.fadeIn(addForm.fadeOut);
};
var showAddForm = function() {
    editForm.fadeOut(addForm.fadeIn);
};
Run Code Online (Sandbox Code Playgroud)

但这会产生以下错误,Uncaught TypeError: Failed to execute 'animate' on 'Element': Valid arities are: [1], but 4 arguments provided.但为什么不起作用?

Guf*_*ffa 8

这是因为将函数作为对象的属性调用是一种特殊的语法,它以对象作为上下文来调用该函数.

当你调用这样的函数时:

obj.func();
Run Code Online (Sandbox Code Playgroud)

然后this将是obj函数内部的引用.

如果您获得对该函数的引用,然后调用它:

var f = obj.func;
f();
Run Code Online (Sandbox Code Playgroud)

然后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));
};
Run Code Online (Sandbox Code Playgroud)