Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何避免将JavaScript ES6模块导出添加到全局范围以用于普通脚本块?_Javascript_Es6 Modules - Fatal编程技术网

如何避免将JavaScript ES6模块导出添加到全局范围以用于普通脚本块?

如何避免将JavaScript ES6模块导出添加到全局范围以用于普通脚本块?,javascript,es6-modules,Javascript,Es6 Modules,到目前为止,我已经设法避免了核心JavaScript编程,但这似乎即将结束。为了准备一个重大的新项目,我正试图在2018年了解最佳实践。我已经阅读了很多关于不同模块方法的书籍,并使用了一些类似Dojo基于AMD的模块。在思考如何设计自己的模块体系结构时,ES6似乎是进行新开发的正确方式。到目前为止,我理解了导入/导出语法,并获得了一些简单的模块。但我目前用HTML加载模块并使用它们的技术“感觉不对劲”。让我把我迄今为止的工作总结一下 模块foo.js import (bar} from '/Sc

到目前为止,我已经设法避免了核心JavaScript编程,但这似乎即将结束。为了准备一个重大的新项目,我正试图在2018年了解最佳实践。我已经阅读了很多关于不同模块方法的书籍,并使用了一些类似Dojo基于AMD的模块。在思考如何设计自己的模块体系结构时,ES6似乎是进行新开发的正确方式。到目前为止,我理解了导入/导出语法,并获得了一些简单的模块。但我目前用HTML加载模块并使用它们的技术“感觉不对劲”。让我把我迄今为止的工作总结一下

模块foo.js

import (bar} from '/Scripts/bar.js'

export function foo() {
    bar();
    console.log("I'm in foo");
}
模块bar.js

export function bar() {
    console.log("I'm in bar");
}
index.html

<head>
    <script type="module">
        import {foo} from "/Scripts/foo.js"
        window.foo = foo;   // save for later but "feels wrong"
   </script>
</head>

<body>
    <script>
        // foo();      // doesn't work - foo by itself is only defined in the module scope
        window.foo();  // unless "stashed" somewhere else
    </script>
</body>

从“/Scripts/foo.js”导入{foo}
window.foo=foo;//留到以后,但“感觉不对”
//foo();//不起作用-foo本身仅在模块范围内定义
window.foo();//除非“藏”在别的地方

也许这是一种合适的技术(我发现了),但我仍然觉得不应该像这样污染全局名称空间。假设这不好,我还应该做什么?

如果您希望函数全局可用,实现这一点的唯一方法是将其放在全局范围内(也称为
窗口
对象)

但是,将内容放在全局范围中的一种更好的方法是,使用某种类型的
全局对象
来包含所有全局对象,而不是将函数/属性名称直接放在
窗口
对象上,这可能会导致与其他第三方库发生冲突

因此,您可以说
globals.foo()
而不是
window.foo()
通过将函数重新导入到许多模块,可以在任何地方访问函数

您只需要将对象添加到全局作用域中,在全局作用域中,状态是跨模块维护和必需的

  • 创建文件ajax.js:make类,例如ajax,用export ajax结束该类
  • 创建main.js文件,type=module
  • 将{Ajax}从“Ajax.js”导入main.js:Ajax类
  • 在main.js中创建:使用var ajax=new ajax()创建一个新类
  • 然后将该变量放入窗口对象:window.ajax=ajax
  • 现在您已经准备好了,可以在应用程序中的任何地方使用该ajax对象
  • 如果您将所有代码捆绑在类中,并将它们放在相同的命名文件中,您将有一个 非常模块化的应用程序

  • 如果您希望函数在全局范围内可用,那么实现这一点的唯一方法就是将其放在全局范围内。除非我误解了你的问题?将内容放在全局范围中的一个更好的方法是使用某种
    globals
    对象来包含所有全局,而不是将实际的函数/属性名称放在
    窗口上,这可能会导致冲突。所以你会说
    globals.foo()
    而不是
    window.foo()
    把它放在全局名称空间中,就像在ES6之前一样?@mhodges:是的,这基本上就是问题所在。没错,除了
    window
    之外,还可以使用其他容器,如您所说的简单属性存储或“名称空间”之类的。感觉模块导入应该在这个级别引入它自己的范围,我只是缺少正确的语法(在询问之前我做了尽职调查/搜索)。但听起来这不是它的工作方式。我想我应该接受@mhodges comment作为答案。@JimHanks如果你使用像Webpack这样的绑定器/模块加载器,你完全可以做你想做的事情。每个js文件都将包含其导入列表,只有在加载该文件时才会加载这些导入。你的全球范围不会受到污染,一切都是自给自足的。如果这就是你想要实现的,我强烈建议你采用这种方法。但是,如果您不想使用bundler/moduleloader,我认为最好使用您自己的名称空间和globals对象bet@JimHanks我还想补充一点(2018年),对于中大型项目,使用捆绑机/模块加载器绝对是一条必由之路。Webpack是目前最简单、最有能力的一个。关于如何起床和跑步,有很多很好的指南。