【问题标题】:node "require" hoisted to top outside of script -- loses access to variables from outer function节点“require”被提升到脚本之外的顶部——无法从外部函数访问变量
【发布时间】:2016-06-17 22:08:37
【问题描述】:

我在 node.js 的主脚本顶部需要不同的文件。我所有的需求语句都被提升到顶部。这会产生一个问题,因为当调用这些导入脚本中的方法时,它们无法访问调用它们的函数(因为由于提升问题,它们不可避免地在这些函数之外定义)。因此,我必须始终在选项对象中传递变量。有没有人遇到过类似的问题?人们使用某种标准的解决方法吗?谢谢!

function outer(){
  //let's pretend we're in a node environment
  //this required script will get hoisted to the very top and therefore lose access to the "something" variable!
  var common = require('../globals/common.js');
  var something = "something";
  

   common.printsomething();//will return "something is not defined"

};

outer();

【问题讨论】:

  • 不是吊装,是对模块工作原理的误解。他们无权访问调用者的范围。
  • 假设common.printsomething() 应该到达something,那么不,没有办法做到这一点。但我感觉我不明白你在问什么。
  • @robertklep:我似乎找不到一个很好的资源来解释这些模块是如何工作的。你有链接吗?谢谢!
  • 模块就像密封的小黑匣子,您可以将其运送到其他功能。盒子里面的代码看不到外面的东西,但是调用代码可以把东西放进盒子里,把东西拿出来。这有点道理吗?

标签: javascript node.js node-modules


【解决方案1】:

嗯。

我认为最终将“某物”传递给 printsomething 方法会更好,就像这样。

common.printfoo('bar'); //returns 'bar'

通常,您在那里所做的并不是节点中的模块如何工作。是的,将一个大程序分解成单独的文件是组织项目的好方法,但恐怕我不得不说你在这里做错了。在“外部”的上下文中,您可以这样做:

/*script.js*/
var common = require('../globals/common.js');

function outer(str){
     common.printsomething(str);//will return "something"
};
var something = 'something';
outer(something);

/*common.js*/
function printthing(str){
   console.log(str);
}
module.exports = {
   printsomething: function(str){
       printthing(str)
   }
}

【讨论】:

  • 你是说我不应该使用“require”将我的代码分解成单独的文件吗?这是不好的做法吗?
  • 不,不。使用不同的 js 文件作为组织者绝对是一个好习惯。但是,请参阅我的示例以了解实际执行此操作的好方法。
  • @orlandomarinella:你应该更清楚文件的分离,这可能有助于杂志更好地理解。
  • 没问题,等一下。
  • 不幸的是,您必须这样做。这是 JavaScript(以及大多数编程语言,就此而言)的工作方式。您还精通哪些其他语言?
【解决方案2】:

module.js:

module.exports.print = function (data) {
    console.log(data);
}

module.exports.add = function (a, b, callback) {
    callback(a + b);
}

main.js

var mymodule = require('module');

module.print('Some data'); //Will print "Some data" in the console
module.add(25, 12, function (result) {
    console.log(result);   //Will print 37
});

如您所见,在 main.js 中,我不需要知道 module.js 的内容即可 wrk。这就是模块的目标:将硬逻辑放在其他地方,以构建更好的代码。 asyncfs 之类的模块庞大而复杂,但我只需要导入它们就可以使用它,并且不需要知道它是如何做到的。

在构建您自己的模块时,请将其视为一个新的工具库,以便您可以在另一个项目中重复使用它,而无需设置特定的变量来使用它们。想象一下,如果两个模块能够为不相关的目标获取您的 var something 的内容,那将是多么混乱!

模块是独立的,可重复使用。将这些“降级”会降低其功效。

编辑:

如果您有很多环境变量,您可以尝试在模块中设置它们一次的模式,但您必须确保提供一种与它们交互的方式。

模块:

var data = {};

function set(key, value) {
    data[key] = value;
}

function get(key) {
    return data[key];
}

function print(key) {
    console.log(data[key]);
}

function add(keyA, keyB) {
    return data[keyA] + data[keyB];
}

module.exports = {
    set: set,
    get: get,
    print: print,
    add: add
};

main.js

var mymod = require('mymod');

mymod.set('data', 'something');
mymod.set('a', 25);
mymod.set('b', 12);

mymod.print('data'); //Print "something"
var c = mymod.add('a', 'b');
console.log(c); //Print 32

【讨论】:

    猜你喜欢
    • 2021-02-24
    • 2017-05-25
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 2020-08-19
    • 2013-08-16
    相关资源
    最近更新 更多