为什么这个名为anonymous js的函数在定义之前有效?

时间:2014-05-02 17:29:19

标签: javascript

我有一个简单的Gulpfile,其中定义了一个任务。在Gulp任务之后定义了一个命名的匿名函数。该任务使用此功能,并且在我希望获得undefined is not a function时正在工作,但我不是。这是代码:

gulp.task('bower', function() {
  var bowerDir = 'bower_components';
  fs.readdir(bowerDir, function(err, dirs) {
    _.each(dirs, function(dir) {
      var directory = dir;
      fs.stat(path.join(bowerDir, dir), function(err, stats) {
        if(stats.isDirectory()) {
          listing('bower_components');
        }
      });
    });
  });
});

var listing = function(dir) {
  console.log(dir);
};

请解释为什么这有效?

2 个答案:

答案 0 :(得分:1)

gulp.task()fs.readdir()fs.stat()都是异步函数。他们在某个时候调用他们的回调函数,而不是立即。这意味着在定义listing之后的代码有可能在实际调用回调之前运行。因此,listing因此在实际使用之前定义。

我不认为这是一种很好的编码方法,因为你依赖于事物的时间安排。


如果您定义了listing函数,请执行以下操作:

function listing(dir) {
  console.log(dir);
}

然后,您不会依赖于时序,因为所有静态定义的函数都会先被解析并提升到它们所定义的范围的顶部,因此在该范围内始终可用,无需计时。


仅供参考,如果您真的希望自己展示,可以添加此日志以查看实际的时间和顺序:

function logTime(msg) {
    console.log((new Date()).getTime() + ": " + msg);
}

logTime("start");
gulp.task('bower', function() {
  var bowerDir = 'bower_components';
  fs.readdir(bowerDir, function(err, dirs) {
    _.each(dirs, function(dir) {
      var directory = dir;
      fs.stat(path.join(bowerDir, dir), function(err, stats) {
        if(stats.isDirectory()) {
          logTime("about to call listing()");
          listing('bower_components');
        }
      });
    });
  });
});

logTime("about to define listing");
var listing = function(dir) {
  logTime("listing() called");
  console.log(dir);
};

答案 1 :(得分:0)

因为匿名函数是一个回调函数,很可能是在列出函数初始化后调用的。