javascript回调是否只是作为函数调用中的参数发送的匿名函数?

javascript回调是否只是作为函数调用中的参数发送的匿名函数?,javascript,Javascript,Javascriptcallbacks是否只是在函数调用中作为参数发送的匿名函数 比如说, mySandwich('ham', 'cheese', function() { alert('Finished eating my sandwich.'); }); 在你的例子中:是的 但在我的例子中:没有 function myCallback() { alert('finished eating my sandwich'); } mySandwich('ham','ch

Javascript
callbacks
是否只是在函数调用中作为参数发送的匿名函数

比如说,

mySandwich('ham', 'cheese', function() {  
   alert('Finished eating my sandwich.');  
  }); 
在你的例子中:是的

但在我的例子中:没有

function myCallback()
{
    alert('finished eating my sandwich');
}
mySandwich('ham','cheese', myCallback);
所以,从你的评论来看,我认为真正的问题是:什么是匿名函数?我已经尽力了,但是现在还很早,所以不要开枪打我

好吧,这是个愚蠢的问题。硬性回答

定义函数时,它使用其
范围
。范围呵呵?好的,让我们重新开始

加载网页时,浏览器将创建一个对象。然后它开始解析您在该文档中编写的所有内容(假设为HTML)

它遇到的每个domeElement都会被放入对象中。widnow.document元素中的每个元素都会在浏览器窗口中呈现/解释

现在,浏览器遇到以下问题:

浏览器会看到
var myVariable
。这告诉他在当前范围内创建一个名为
myVariable
的变量(同样是这个词)。当前范围是
窗口
(浏览器创建的窗口对象)。因此,它将变量添加到窗口对象:

window.myVariable === myVariable
myButton = document.getElementById('myButton'); // === window.document.getElementById('myButton');
myButton.addEventListener('click', function()
{
    alert('I am so awesome');
});
函数也是如此

function myAwesomeFunction()
{
    alert('I am so cool');
}
在当前作用域(
窗口
)内创建名为
myAwesomeFunction
的函数。所以再次强调:

window.myAwesomeFunction === myAwesomeFunction
但是如果我想创建一个我没有其他代码可以访问的函数呢?如果我想要一个只在单击某个特定按钮时才存在的函数,该怎么办

好吧,输入匿名函数。这些是在匿名作用域中声明的函数。无法使用窗口对象访问它们:

window.myVariable === myVariable
myButton = document.getElementById('myButton'); // === window.document.getElementById('myButton');
myButton.addEventListener('click', function()
{
    alert('I am so awesome');
});
现在,传递到eventlistener的函数只存在于eventlistener中。它甚至连名字都没有。所以它的作用域是“按钮的点击事件”,但我们无法从外部访问它,因为它没有名称。因此,匿名功能


一个好的读物应该是谷歌的东西,比如“javascript范围”、“javascript窗口对象”。。。很多优秀的文章都对我向您抛出的所有单词进行了更深入的解释。

JavaScript回调是作为值传递到异步函数中的函数,用于继续

函数是值: 因此,在JavaScript中,可以传递类似于值的函数。您可以通过多种方式引用函数:

  • 传递一个文本匿名函数作为回调函数

    doSomeWork(function (err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    });
    
    doSomeWork(function magicalCallback(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    });
    
    var someFunction = function callItWhatYouWant(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    }
    
    // reference the callback stored in the someFunction variable
    doSomeWork(someFunction);
    
    function callItWhatYouWant(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    }
    
    // reference the callback function using the function name
    doSomeWork(callItWhatYouWant);
    
  • 传递一个文本命名函数作为回调函数

    doSomeWork(function (err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    });
    
    doSomeWork(function magicalCallback(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    });
    
    var someFunction = function callItWhatYouWant(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    }
    
    // reference the callback stored in the someFunction variable
    doSomeWork(someFunction);
    
    function callItWhatYouWant(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    }
    
    // reference the callback function using the function name
    doSomeWork(callItWhatYouWant);
    
    (命名每个函数是一个明智的想法,因为您可以在堆栈跟踪中看到它)

  • 传入一个变量的值,该变量恰好将函数存储为回调函数

    doSomeWork(function (err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    });
    
    doSomeWork(function magicalCallback(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    });
    
    var someFunction = function callItWhatYouWant(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    }
    
    // reference the callback stored in the someFunction variable
    doSomeWork(someFunction);
    
    function callItWhatYouWant(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    }
    
    // reference the callback function using the function name
    doSomeWork(callItWhatYouWant);
    
  • 通过引用函数名作为回调传入函数

    doSomeWork(function (err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    });
    
    doSomeWork(function magicalCallback(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    });
    
    var someFunction = function callItWhatYouWant(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    }
    
    // reference the callback stored in the someFunction variable
    doSomeWork(someFunction);
    
    function callItWhatYouWant(err, result) {
        if (err) {
            throw new Error(err);
        } else {
            console.log(result);
        }
    }
    
    // reference the callback function using the function name
    doSomeWork(callItWhatYouWant);
    
  • 继续? 继续就是下一步。当您调用异步函数时,它需要通知您该函数已完成。回调将作为下一步,即异步函数完成后将回调

    所以回调函数只是一个用于特定目的的函数参数,也就是继续

    回调签名 回调函数应该采用哪些参数没有标准,但在Node.js社区中,我们采用了通用签名

    function (err, result)
    
    其中
    err
    是一个
    Error
    对象,如果发生了不好的事情,或者
    null
    如果事情成功。如果出现问题,
    结果
    通常是
    未定义的
    ,否则它包含结果。因此,您的回调通常由以下两种方式调用:

    callback(new Error("oops"));
    

    还要注意,异步函数的最后一个参数作为回调参数是正常的

    function callLater(delay, args, callback) {
        setTimeout(function () {     
            callback(null, args);
        }, delay);
    }
    

    是的,除了它们不必是匿名函数,还有回调的定义。其他两个答案涵盖了回调和匿名函数的细节,但我在第一次学习时也有类似的困惑,所以我想添加一个缺失的部分。那么,你的例子是:

    mySandwich('ham', 'cheese', function() {  
       alert('Finished eating my sandwich.');  
       }); 
    
    我注意到大多数回调解释都是这样的——它们不包括较大函数的声明,在本例中是mySandwich。但是是的,传递到的函数确实需要显式调用回调函数才能运行。因此,您的mySandwich函数可能如下所示:

    function mySandwich(meat, topping, callback) {
        //some code here using meat and topping
        //some code here about eating the sandwich
        callback();
    }
    
    因此,您的代码将这些参数(包括函数)传递到mySandwich函数中,然后由该函数调用它。因为很多时候我们使用的顶级函数是一个库中的方法,而不是我们自己代码的一部分,所以我们实际上看不到调用回调的步骤,但回调仍然会发生,而且不会自动执行


    是的,回调实际上只是一个函数,作为一个参数传递给另一个函数,然后调用它,通常是在这个更大的函数中发生的最后一件事。回调不止这些,但它们的操作规则与其他函数相同,在某些地方必须声明它们,在某些地方必须调用它们,否则它们不会运行。

    请您详细解释一下。无法理解幕后发生了什么?@AnkurAggarwal我补充了一些话