2014-05-22 37 views
-1

我想知道在Javascript中传入回调函数的作用域是什么。javascript回调函数的作用域

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

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

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

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

当我调用func1()..看起来好像这个额外的函数层失去了对callback()的引用。我可以从func2中调用callback(),但不能调用func3。任何人都可以请指教?

+1

你是怎么调用这些函数的? – PeeHaa

+0

适用于我。 http://jsfiddle.net/QZL6M/ – JJJ

+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范围包括所有变量的回调,FUNC2和FUNC3。

调用FUNC1会提醒你好,只有当它被调用的,因为所有的功能都使用函数表达式,而不是函数声明一样

回调函数(){警报(“你好”)}初始化片段底部。

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> 
+0

Javascript是单线程的并在函数级块中执行。这里的竞赛状况如何? –

+0

我想竞赛条件不是这里的正确术语。我删除了警报,并更新了一个元素,因此内容越来越慢,看不清发生了什么。无论哪种方式,我把按钮,所以每个功能可以单独运行。当我写这篇文章的时候我很匆忙。我会更新以删除竞赛条件评论。 – ubergoober

+0

@JoeFrambach ..我也习惯于使用节点,所以处理回调和异步任务的竞争条件让我偏执,当我没有得到我期望的东西时。 :) – ubergoober