了解嵌套回调和范围?

问题描述 投票:1回答:2

我知道有很多关于回调的文档和课程。我已经阅读了许多这些资源,但对于这个特殊问题,我不明白发生了什么。并且,我认为帮助解决这个特殊问题将有助于我更好地理解回调。

总之,我不明白为什么我可以在主'readFile()'函数的一部分中访问'ext',但是我不能将它传递给该函数中的函数,即'filterData()'函数。

感谢您帮助理解这一点。

const fs = require("fs");
const path = require("path");

const dir1 = process.argv[2];
const fileType = process.argv[3];  
const whenDone = function(err, data) {
  if(err) {
    console.log(err);
  } else {
  for(i = 0; i < data.length - 1; i++) {
    console.log(data[i]);
    }
  }
}

let arr = [];


function readFile(dirName, ext, callback) {
  fs.readdir(dirName, function (err, data) {
    if (err) {
      return callback(err, null);
    }
      // ext and data are defined here:
      console.log(ext, data);
      function filterData(ext) {
        // ext and data are not defined here?
        console.log(ext, data);
        return data.filter(function(files) {
          return arr = files.includes(ext);
          console.log(arr);
        });
        return callback(null, arr);
      }
  });
}




readFile(dir1, fileType, whenDone);
javascript node.js callback
2个回答
1
投票

原因是在嵌套函数(filterData)中,您声明了一个参数(本质上是一个局部变量),它具有相同的名称(ext),它已经存在于更高的范围(readFile)中,因此,在filterData函数的持续时间内, ext指的是传递给它的东西,而不是传递给extreadFile。这称为"hiding" or "shadowing",当较小的作用域声明已在较高作用域中声明的标识符时发生。

我写过关于这个here的文章。

如果您只是更改嵌套函数的参数名称并确保在嵌套函数中引用这些参数名称,它将起作用:

// The parameters of a function essentially become local variables
// to that function. The names you give will exist throughout that
// function's scope.
function readFile(dirName, ext, callback) {
  fs.readdir(dirName, function (err, data) {
    if (err) {
      return callback(err, null);
    }
    console.log(ext, data);

      // To avoid shadowing/hiding name the nested function's
      // arguments something that doesn't conflict with existing
      // identifier names in the higher scope.
      function filterData(ext2) {
        // Now, there is no collission:
        console.log(ext2, data);
        return data.filter(function(files) {
          return arr = files.includes(ext2);
          console.log(arr);
        });
        return callback(null, arr);
      }
  });
}

这是一个简单的例子:

var x = 10;
var y = 20;

function foo(){
  var x = true; // <-- This x shadows the one from the higher scope
  console.log(x,y); // true 20, not 10, 20
}

foo();
console.log(x,y);  // 10 20 because the scope of foo is not available here

1
投票

您正在嵌套函数中定义参数名称ext,它会影响上部范围ext参数。因此,您可以将其更改为其他内容,并且您将拥有上限范围ext param访问权限。

© www.soinside.com 2019 - 2024. All rights reserved.