了解嵌套回调和范围?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解嵌套回调和范围?相关的知识,希望对你有一定的参考价值。

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

总之,我不明白为什么我可以在主'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);
答案

原因是在嵌套函数(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
另一答案

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

以上是关于了解嵌套回调和范围?的主要内容,如果未能解决你的问题,请参考以下文章

活动结果片段索引超出范围:0x20001

反应 setState 嵌套数组回调

使用嵌套片段和动画对象

嵌套类的范围?

Facebook状态回调不适用于片段

将片段添加到片段中(嵌套片段)