调用非导出函数的 Nodejs 导出函数

Nodejs exporting function that calls non exported function

本文关键字:函数 Nodejs 调用      更新时间:2023-09-26

这是一个好奇类型的问题。

假设有一个文件库.js如下所示:

function alpha(){
    console.log("in alpha");
    beta();
    console.log("back in alpha");
}
function beta(){
    console.log("in beta")
}
module.exports = {
    alpha:alpha
}

当另一个文件(例如 main(需要此库时.js则从此模块调用 alpha 函数将如下所示:

var lib = require("library.js")
lib.alpha();
//outputs:
//in alpha
//in beta
//back in alpha

但是,beta(( 函数并没有真正导出。这是否意味着 NodeJS 在库.js文件中查找 beta((?如果有人能详细解释这个过程,那就太好了。

这取决于函数的作用域,您始终可以从同一作用域或所有周围的作用域调用函数或变量。作用域通常是一个函数语句,它可能被全局作用域包围(在浏览器中,全局作用域是窗口(。您可以嵌套函数,内部函数可以访问它们自己的变量以及其周围作用域的变量。看看这个例子:

var varInGlobalScope = 'global'; // This is always accessible
var functionInGlobalNamespace = function () {
  // This is accessible inside the function 'functionInGlobalNamespace'
  // and all nested functions but not from the global Scope
  var varInFunction = 'in function';
  var functionInFunction = function () {
    // This is accessible inside the function 'functionInFunction'
    // but not from 'functionInGlobalNamespace' or the global Scope
    var varInFunctionInFunction = 'in function in function';
    console.log(varInFunctionInFunction); // works
    console.log(varInFunction); // works
    console.log(varInGlobalScope); // works
  }
  console.log(varInFunctionInFunction); // fails
  console.log(varInFunction); // works
  console.log(varInGlobalScope); // works
}
console.log(varInFunctionInFunction); // fails
console.log(varInFunction); // fails
console.log(varInGlobalScope); // works

此作用域始终存在,这意味着如果您将一个函数构建为另一个函数的公共成员并从中调用私有成员,则该函数可以工作。但是,如果您不在正确的范围内,它将失败。如果扩展对象的原型,则此行为非常重要。

var Demo = function () {
  var privateFunction = function () {
    console.log('private');
  };
  this.publicMethod = function () {
    console.log('public');
  };
  this.publicMethodToCallPrivateFunction = function () {
    privateFunction();
  };
}
Demo.prototype.tryCallingPublicMethod = function () {
  this.publicMethod();
};
Demo.prototype.tryCallingPrivateFunction = function () {
  privateFunction();
};
var demo = new Demo();
demo.publicMethod(); // works
demo.publicMethodToCallPrivateFunction(); // works
demo.tryCallingPublicMethod(); // works
demo.tryCallingPrivateFunction(); // fails

现在是 Node 的"魔术"部分.js因为如果您构建一个模块以在另一个模块或文件中需要它,则必须将所有可导出的内容放入特殊对象module.exports中。这基本上是一个由 require 函数返回的对象,但正如我们在示例中了解到的那样,该函数的整个 Scope 仍然存在。

在这种处理中,还有其他一些方面可能很重要,但解释这些方面会膨胀答案。

作为提示,您可以完美地使用它来实现私有功能,并且只为用户提供干净的界面。例如,将一个巨大的函数拆分为几个小块以保持干净的代码库。

之所以这样做,是因为关闭和吊装。

首先,nodejs 在文件内容周围创建一个周围的块,如下所示:

(function (exports, require, module, __filename, __dirname) {
    function alpha(){
        console.log("in alpha");
        beta();
        console.log("back in alpha");
    }
    function beta(){
        console.log("in beta")
    }
    module.exports = {
        alpha:alpha
    }
});

函数声明总是在代码执行之前被解析,并始终提升到顶部。所以他们彼此认识。

函数定义如下:

 function beta(){
   console.log("in beta")
 }

可以看作是对此的简写:

 var beta = function beta(){
    console.log("in beta")
 }

不同之处在于,函数的声明和定义都提升到范围的开头。

生成的代码将如下所示:

(function (exports, require, module, __filename, __dirname) {
   var alpha, beta;
   alpha = function alpha(){
       console.log("in alpha");
       beta();
       console.log("back in alpha");
   }
   beta = function beta(){
       console.log("in beta")
   }
   module.exports = {
       alpha:alpha
   }
});

未在模块中导出的函数作为私有方法工作,不能从外部调用。只有当导出的其他函数使用它时,它们才能使用,否则将是无法访问的代码。