了解回调和相关的词法范围

时间:2016-03-12 06:27:15

标签: javascript callback lexical-scope

我试图通过setTimeout函数了解回调。 我有两组代码:

for (var i = 1; i <= 10; i++) {
        (function(callback,i){
          setTimeout(function(){
            callback(i)
          }, 0);
         })(function(val){console.log(val)},i);

它可以正常打印1,2,3,.... 10

但是当我试图将setTimeout的回调函数抽象为:

for (var i = 1; i <= 10; i++) {
        (function(callback,i){
          setTimeout(func, 0);
         })(function(val){console.log(val)},i);
        }
function func(){
    callback(i)
  }

它给出了错误陈述

Uncaught ReferenceError: callback is not defined

我知道func函数声明的词法范围存在一些问题。但无法理解原因。 请帮我理解这一点。

3 个答案:

答案 0 :(得分:2)

callback未在func中定义。您可以将func作为参数传递给IIFE,使用Function.prototype.bind()i传递给callbackfunc

for (var i = 1; i <= 10; i++) {
  (function(callback, i) {
    setTimeout(callback.bind(null, i), 0);
  })(func, i);
}

function func(val) {
  console.log(val)
}

答案 1 :(得分:2)

它抛出引用错误,因为函数func它有一个范围,其中没有callback的声明。您可以通过将回调作为参数传递给func来修复它。

for (var i = 1; i <= 10; i++) {
  (function(callback, i) {
    setTimeout(func, 0, callback.bind(null, i)); //Pass the callback here as a parameter to func. 
                                   //(setTimeout can pass its >2 parameter as 
                                   //its callback parameter)
  })(function(val) {
    console.log(val)
  }, i);
}

function func(callback) { //receive the callback here and use it.
  callback();
}

答案 2 :(得分:1)

func中,您没有引用您在IIFE中声明的callback。它开始查看当前范围,即func范围。然后尝试在全局范围内查找,它也没有在那里定义。最后它会抛出错误

你需要将refarence传递给这个回调参数,引用该函数来消除这个错误。

for (var i = 1; i <= 10; i++) {
        (function(callback,i){
          setTimeout(func.bind(null,callback,i), 0);
         })(function(val){console.log(val)},i);
        }
function func(callback,i){
    callback(i)
  }