javascript回调函数的范围

时间:2014-05-22 21:53:10

标签: javascript function callback scope

我想知道Javascript中传递的回调函数的范围是什么。

callback = function() {
    alert('hello');
}

func1 = function() {
    func2(callback);
}

func2 = function(callback) {
    func3(callback);
}

func3 = function(callback) {
    callback();
}

当我调用func1()时,好像这个额外的函数层失去了对callback()的引用。我可以在func2中调用callback(),但不能调用func3。任何人都可以建议吗?

2 个答案:

答案 0 :(得分:0)

你应该看到你的代码写成

var callback;
var func1;
var func2;
var func3;

callback = function() {
    alert('hello');
}

func1 = function() {
    func2(callback);
}

func2 = function(callback) {
    func3(callback);
}

func3 = function(callback) {
    callback();
}

func1范围包括所有变量callback,func2和func3。因为所有函数都是使用函数表达式初始化的,而不是像

那样的函数声明
  

function callback(){alert(' hello');}

只有在你的代码片段底部调用它时,调用func1才会提醒你。

答案 1 :(得分:0)

希望我已在此jsFiddle中解释了其中的一些内容。查看JS中的注释。这是匆忙完成的,所以随时更新/评论/问题。如果你想在本地进行测试,代码如下。

<!DOCTYPE html>
    <html>
      <head>
      </head>
      <body>

      <div id="test">
      </div>

      <script>


        // We're going to name our /callback/ something else to help with
        // the confusion of using /callback/ wording everywhere.
        var showMessage = function(message) {
          document.getElementById("test").innerHTML= message;
        }

        var tellMe = function(message) {
          document.getElementById("test").innerHTML = message;
          return "Oh yes we did!";
        }

        // here we'll have one called callback just to show the name callback isn't anything special
        var callback = function(message) {
          document.getElementById("test").innerHTML= message;
        }

        // doesn't show anything, because you're not passing in a call back.
        // if we wanted this to work we would have a param called callbackTest and
        // we's pass in a function to be called back.
        func1 = function() {
          func2(callbackTest("Hi from func1"));
        }

        // does show message because you're not calling a callback, you're calling a function directly. Which is what you were doing above, just that there happened to not be a function called callback
        // see explination below why we don't see Hi from func2, but Hi from func1_5 instead
        func1_5 = function() {
          func2(callback("Hi from func1_5"));
        }

        // here we're actually accepting a callback function named showMessage and using that as our callback by assigning it to the callback parameter variable. (remember, callback is not a fancy statement or call or anything. It's just a commonly named variable for.... callbacks ;) )
        func2 = function(callback) {
          // what you're doing here is actually passing the result of calling the callback (showMessage) to func3, and not the function. So you're actually executing the callback (showMessage) with the "Hi from func2", which outputs that, but returns nothing. So you're not passing anything at all to func3.
          func3(callback("Hi from func2"));
        }

        // so here we'll show the previous problem, but working to provide insight.
        // we're passing in a different /callback/ called tellMe. This function actually returns a string.
        func2_5 = function(callback) {
          func3(callback("Hi from func2_5"));
        }

        // here you're actually passing in a function to this as a callback, which is actually the showMessage function we pass in below.
        func3 = function(callback) {
          // the thing is, the callback variable is now a string and not a function because we got the result of the passed in callback call from above.
          // so this will show a string for callback ("Oh yes we did!")
          document.getElementById("test").innerHTML = callback;
          // and this won't show anything because callback is not a function in this scope
          if (typeof(callback) !== "function") {
            alert("callback isn't a function");
          }else {
            callback(("Hi from func3"));
          }
        }

        func4 = function() {
          if (typeof(callback) === "undefined" ) {
            alert ("the callback variable was never defined")
          } else {
            callback(("Hi from func4"));
          }
        }



      </script>

      <button onclick="func1();">func1</button>
      <button onclick="func1_5()">func1_5</button>
      <button onclick="func2(showMessage);">func2</button>
      <button onclick="func2_5(tellMe);">func2_5</button>
      <button onclick="func3();">func3</button>
      <button onclick="func4()">func4</button>

      </body>
    </html>