在ES6中使用IIFE命名?

ma1*_*w28 8 namespaces global-variables iife ecmascript-6 babeljs

显然,ES6不需要命名空间,因为每个文件都是一个单独的模块.

但是,如何避免全局命名空间干扰?

例如,巴贝尔编译我scripts/main.js仅仅通过替换文件constvar.

var alert = 'This line doesn\'t do anything.'
window.alert(alert)
Run Code Online (Sandbox Code Playgroud)

ANS使用IIFE的命名空间(如下所示)可防止名称冲突:

const ANS = (function () {
  const alert = 'This works'
  window.alert(alert + '.')
  return {alert: alert + ' too.'}
})()
alert(ANS.alert)
Run Code Online (Sandbox Code Playgroud)

向命名空间添加属性ANS比将它们添加到全局命名空间更简洁window,或this.而且,IIFE提供了进一步的封装.

那么,不是第二种方式,即用IIFE创建自定义命名空间,比第一种更好吗?如果是这样,在ES2015中有更新/更好的方法吗?Babel为什么不为我这样做?

Ber*_*rgi 9

显然,ES6不需要命名空间,因为每个文件都是一个单独的模块.

不完全是.每个模块都有自己的范围,这是正确的,但不是每个文件都是模块.ES6中的脚本仍然与ES5中的脚本一样,并且在全局范围内执行.
在这些脚本中,您仍然需要尽可能多地避免全局变量,通常不要声明/分配任何变量,或者将"模块"包装在IEFE中以赋予它单独的变量范围.

在ES6中有更新/更好的方法吗?

您可以使用块和词汇变量声明(let,const,function):

{
    const msg = 'This line doesn\'t do anything.'
    window.alert(msg);
}
// msg is not defined here
Run Code Online (Sandbox Code Playgroud)

或者您可以在IEFE中使用箭头功能,这样您就可以使用它this来引用全局对象而无需使用.call(this)):

(() => {
    var msg = 'This line doesn\'t do anything.'
    window.alert(msg);
})();
Run Code Online (Sandbox Code Playgroud)

但是,如何避免全局命名空间干扰或命名冲突?

在ES6模块中,除了内置对象和全局对象之外,没有什么是全局的.避免修改它们.

当然,您需要注意模块名称之间的冲突 - 如何执行此操作应在模块加载器的解析器机制的文档中进行说明.

  • 你有理由想避开模块吗?大多数人使用Webpack或browserify将其所有模块代码捆绑到一个脚本中. (2认同)

Fel*_*ing 2

但是,如何防止从模块内覆盖全局变量?

你不能。与 ES5 相比,这方面没有任何变化。建议仍然是:避免使用全局变量。