Commonjs(值拷贝和动态声明) commonjs是基于服务端而设计的,规定一个文件就是一个模块,每个模块都有自身的作用域,所有的变量和函数都只有自己能访问,每个模块内部都有一个module对象,代表当前模块...(这是区别原生script文件的最大区别,原生script在顶层作用域声明变量或函数,会导致污染全局环境)。.../a') console.log(a); // { a: 1, b: 2 } ESM 直到2015,es6定义了js模块标准(ESM),使之有了模块的概念。...esm是静态声明的: 必须在模块首部声明 不可以使用表达式或变量 不允许被嵌套到其它语句中使用 因为是静态加载的,在es6代码的编译阶段,就可以分析模块间的依赖关系,可以进行编译过程的优化 es6 module...es6 module静态模块结构有助于确保模块间传递的值或接口类型是正确的 编译器优化。commonjs导入的是一个对象,而es6支持直接导入变量,减少引用层级,效率更高。
ES5中只有两种声明变量的方法,var和function两个关键字,而Es6新增了let,和const,另外,还有两种就是import,和class关键字 01 var声明及变量提升 在Es5中只有函数作用域和全局作用域...中使用var声明的变量,没有块级作用域,会污染全局变量,如果使用不当,会产生一些达不到自己预期的效果,所以在Es6中就有了块级作用域 块级作用域:用于声明在指定的块的作用域之外无法访问的变量 函数内部...,指向一个对象,不可变的只是这个地址,不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新的属性 07 关于全局块作用域的绑定 当var,和function被用于全局作用域时,它会创建一个新的全局变量对象作为全局对象...(浏览器环境中的window对象),使用var会覆盖一个已经存在的全局变量 let,const和class命令声明的全局变量不属于全局对象的属性,声明的变量不会提升,而且只可以在声明这些变量的代码块中使用...不能在声明变量前访问它们 如果不想为全局对象创建属性,则使用let和const要安全得多 如果希望在全局对象下定义变量,仍然可以使用var,这种情况下常见用于在浏览器中跨ifram或跨window访问代码
类库项目的构建如果需要注入 polyfill 的话,最好使用 @babel/transform-runtime,因为它提供了一种不污染全局作用域的方式。...细心的小伙伴可能会发现了,编译后的 generator 函数依赖了全局的 regeneratorRuntime 这个对象。...,会污染全局作用域。...作用域范围 首先,老生常谈 @babel/plugin-transform-runtime 编译后添加的 polyfill 并不会污染全局作用域,而 preset-env 并不会污染全局作用域。...Promise 的确添加了 polyfill 但是明显可以看到这是一种污染全局作用域的作用,会为全局添加 Promise。
不适合浏览器环境,因为它需要同步 I/O 操作。作用域ESM 模块始终运行在严格模式下,并且每个模块都有自己的作用域。相比之下,CJS 模块共享一个全局作用域,可能引发作用域污染的问题。...JavaScript 的官方标准,在现代浏览器和 Node.js 环境中原生支持。...模块化设计:强制使用严格模式,模块作用域隔离,减少全局污染。并行加载:浏览器可以更高效地加载 ESM 模块。ESM 的缺点兼容性问题:旧版本的 Node.js 和一些构建工具对 ESM 支持有限。...优化难度:动态加载机制限制了静态分析和优化的可能性。作用域问题:可能引发全局作用域污染,导致模块间冲突。适用场合选择 ESM 的场景:构建现代化的前端项目,充分利用浏览器的模块加载特性。...需要进行 Tree Shaking 优化的项目。长期维护的项目,考虑到标准化和可移植性。选择 CJS 的场景:编写 Node.js 中的服务端代码,尤其是小型工具或脚本。
举例来说, 两个不同项目的全局作用域都有一个类 Foo, 这样在编译或运行时造成冲突....Bar { … }; }; 优点: 当嵌套 (或成员) 类只被外围类使用时非常有用; 把它作为外围类作用域内的成员, 而不是去污染外部作用域的同名类....优点: 某些情况下, 非成员函数和静态成员函数是非常有用的, 将非成员函数放在名字空间内可避免污染全局作用域....作用域的使用, 除了考虑名称污染, 可读性之外, 主要是为降低耦合, 提高编译/执行效率....匿名名字空间说白了就是文件作用域,就像 C static 声明的作用域一样,后者已经被 C++ 标准提倡弃用。
模块化的优点: 文件里声明的变量会被隔离,不会暴露到全局,可以有效解决以往变量污染全局空间的问题; 更容易看出代码之间的依赖关系,看文件头的的导入代码就知道; 方便多人协作,各自开发自己的模块,而不冲突...; 不用担心文件引入的顺序; 方便以文件为单位做单元测试; 模块化解决了变量污染、代码维护、依赖顺序问题。...= '前端西瓜哥'; // 或 exports.userName = '前端西瓜哥'; 每个文件都可以访问到一个 module 对象,其下的 exports 属性是一个空对象,你可以给它加上属性,.../user'); // 或不使用任何导出内容,但希望指定对应模块文件的副作用(如给全局注入变量) require('....import 需要写在模块文件最外层,不能在其他任何作用域内,且 import 会做提升; require 永远是同步加载代码。import 一般也是同步的,但也能做动态加载,此时则是异步的。
但是由于 浏览器的版本标准不一致,尤其是移动端(各个手机有自带的默认浏览器,再加上QQ,UC, 360,百度,夸克)浏览器众多,对我们前端开发的H5页面兼容性未知,当你使用了某个新的API时,有概率会直接在某些小众或者低版本浏览器上报错...plugin-transform-runtime 在babel/runtime的基础上解决了全局变量污染的问题,从一个统一的模块中引入,避免了对全局变量及其原型的污染。...corejs": 3 // 默认为true 表示将这些工具函数抽离成为工具包引入而不必在每个模块中单独定义 "helpers": true, // 切换生成器函数是否污染全局...// 为true时打包体积会稍微有些大 但生成器函数并不会污染全局作用域 // 为false时体积小 "regenerator": false,...} ] ] } 如果是开发类库 类库项目的构建如果需要注入 polyfill 的话,最好使用 @babel/transform-runtime,因为它提供了一种不污染全局作用域的方式。
文章目录 ✔️前言 内容 作用域 `global`、`window`、`document`的区别 预编译 1.前奏 2.四部曲 3.全局对象 1.预编译部分 2.详细介绍——IIFE 总结 ✔️前言...本篇给大家带来js语法核心基础之预编译的讲解 内容 作用域 JS有两种作用域:全局作用域和函数作用域 内部的作用域能访问外部,反之不行;访问时从内向外依次查找 如果在内部的作用域中访问了外部,则会产生闭包...) 闭包是由作用域产生的一种现象 JS 中所有函数都是闭包 内部作用域能访问的外部,取决于函数定义的位置,和调用无关 作用域内定义的变量、函数声明会提升到作用域顶部——预编译;在JS中只有var和function...动图解析预编译的作用结果(仔细观察每一步变化,帮助理解;另外提供一种思路:断点调试(此处不再演示)): 3.全局对象 1.预编译部分 不同点: 第一步创建一个 GO 对象(Global...: 全局对象的属性可以被直接访问 给未声明的变量赋值,实际就是给全局对象的属性赋值,参考前文的预编译 所有的全局变量、全局函数都会附加到全局对象 这称之为全局污染,又称之为全局暴露,或简称污染
在浏览器中,HTML5 制定了 Web Worker 标准来解决 JS 大规模计算导致的阻塞 UI 渲染的问题。而 Node 中,使用 child_process 创建子进程来应对单线程带来的问题。...它的生成方式与 JavaScript 原型链或者作用域链的查找方式十分类似。Node 会逐个尝试模块路径,直到找到模块或者查找到根目录位置。可以看出,当文件路径比较深的时候,模块查找会比较耗时。..., __filename, __dirname) { // 模块的代码实际上在这里 }); 这样每个模块文件之间都进行了作用域隔离,包装之后的代码会通过 vm 原生模块的 runInThisContext...() 方法执行(类似 eval,只是有明确的上下文,不污染全局)。...编译 JS 核心模块。首先在引入 JS 的核心模块的过程中,经历了模块包装器的过程,然后导出 exports 对象。
模块化的好处显而易见: 作用域隔离:模块中的代码默认不会暴露在全局作用域中,避免了命名冲突和不必要的污染。 依赖管理:显式声明模块之间的依赖关系,使代码更清晰、结构更合理。...普通 JavaScript 文件中,所有的代码都在全局作用域执行,这意味着函数、变量和对象默认会附加到全局对象(在浏览器中是 window 对象)上。...模块中的代码默认是私有的,即每个模块都有自己独立的作用域,模块内部定义的函数和变量不会自动附加到 window 或其他全局对象上。 这是为了避免全局污染,减少不同模块之间可能发生的命名冲突。...全局变量的问题:为什么普通脚本中的全局变量或函数在模块化后不再可用 由于模块的作用域是私有的,导致在普通脚本中定义的全局变量或函数,在模块化后无法直接作为全局对象的一部分被访问。...在模块化转换过程中,注意作用域变化、全局对象的使用、依赖管理和工具链的支持,能帮助你顺利过渡并从模块化中受益。 模块化不仅让代码更干净和可维护,还通过工具链支持实现了更高效的代码优化。
由于函数具有独立作用域的特点,最原始的写法是使用函数来作为模块,几个函数作为一个模块,但是这种方式容易造成全局变量的污染,并且模块间没有联系。...现在最常用的是立即执行函数的写法,通过利用闭包来实现模块私有作用域的建立,同时不会对全局作用域造成污染。 ----问题知识点分割线---- 什么是作用域链?...首先要了解作用域链,当访问一个变量时,编译器在执行这段代码时,会首先从当前的作用域中查找是否有这个标识符,如果没有找到,就会去父作用域查找,如果父作用域还没找到继续向上查找,直到全局作用域为止,,而作用域链...区别 varletconst是否有块级作用域 × ✔️ ✔️ 是否存在变量提升 ✔️ × × 是否添加全局属性 ✔️ ×...和文件并返回 200; 很多网站的资源后面都加了版本号,这样做的目的是:每次升级了 JS 或 CSS 文件后,为了防止浏览器进行缓存,强制改变版本号,客户端浏览器就会重新下载新的 JS 或 CSS
模块化的演变 为什么要有 JS 模块化呢?在浏览器中,顶层作用域的变量是全局的,所以项目稍微复杂点,如果引用的 js 非常多的时候,很容易造成命名冲突,然后造成很大意想不到的结果。...为了避免全局污染,JS 前辈们想了很多办法,也就是前端的模块化的演变过程,可以参考我的视频:前端模块化演变 模块化演变过程: 对象封装 所有的方法和属性封装到一个对象中 所有的访问通过对象来访问,...只污染一个对象,尽量避免污染其他。...私有空间 私有空间的变量和函数不会影响全局作用域 公开公有方法,隐藏私有属性 // => 给单个文件里面定义的局部变量都 变成 局部作用域里面的变量。...而且您也看到了,我们的代码都会被包装到一个函数中,所以我们的代码的作用域都是在这个包装的函数内,这点跟浏览器的window全局作用域是不同的。
自执行的匿名函数IIEF 我们知道,在浏览器中有一个window,我们的变量声明会或多或少的影响全局环境 但是人们发现,由于函数的特殊作用通过闭包的方式,可以将多余的变量,保存在闭包中,只留下个别变量挂在全局...他的作用就是JavaScript 查找某个未使用命名空间的变量时,会通过作用域链来查找,作用域链是跟执行代码的 context 或者包含这个变量的函数有关。'...with'语句将某个对象添加到作用域链的顶部,如果在 statement 中有某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值。...,我的window和之前的不共用, 那么问题就迎刃而解了,我只需要将每个应用的内容保存到一个对象中,如果在对象中,找不到的情况下,再去全局window中找,这样既保证了,每个引用的不同部分的隔离,有保证了...,这个环境由浏览器实现了与主环境的隔离。
补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用 域方面、IO方面、函数方面、指针方面、宏方面等。 2. 为后续类和对象学习打基础。 1....C++又新增了许多,我们不用看,也不用管。 2. 命名空间 在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存 在于全局作用域中,可能会导致很多冲突。...使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。...命名空间是我们要学的第一个关键字,它可以定义一个域出来,定义的域叫做命名空间域。作用域是域里面的一种。 几种常见的域:类域、命名空间域、局部域、全局域。局部域和全局域都是一种作用域。 ...using namespace bit这个叫做展开命名空间域,也就是展开bit的命名空间。展开也就是相当于暴露在全局。命名空间域展不展开编译时是否去命名空间中搜索,展开就去搜索,不展开就不去搜索。
从而将目标浏览器下不支持的内容在项目入口处进行全量引入,分别挂载在对应全局对象上从而达到 polyfill 的作用。...polyfill 在对应的全局对象上增加功能实现,这样无疑是会污染全局环境。...@babel/runtime 简单来说 @babel/runtime 提供了一种不污染全局作用域的 polyfill 的方式,但是不不够智能需要我们自己在代码中手动引入相关 polyfill 对应的包。...helpers: true, // 切换生成器函数是否污染全局 // 为true时打包体积会稍微有些大 但生成器函数并不会污染全局作用域...仅仅抽离保留我们代码中使用到的新语法提供 polyfill 实现,但是 @babel/runtime 相对于 usage 而言还存在一个更加值得注意的点它并不会污染全局作用域。
Babel转换器 因为ES6提供了很多新特性,造成了很多浏览器不能够完美的支持所有新特性的问题,然而鉴于新特性的好用,很多公司会选择使用ES6进行开发,针对兼容问题,我们可以选择一个转码器对ES6进行转码...不同于var声明的变量, 1)let或const所声明的变量只在其所在的代码块中有效 2)let或const不存在变量提升,因此必须在声明之后使用变量 3)会形成暂时性死区,当let或const在块级作用域中声明后...,比如加个属性~~) 2 块级作用域 上面我们谈到了块级作用域,事实上ES5中是不存在块级作用域的,这也是《JavaScript高级程序设计》中重点提到的,但是这其实在很多场景中是不合理的。...(s[i]); } console.log(i); // 5 let就可以阻止这些事情的发生,因为它为JS新增了块级作用域。...1)保证了外部作用域无法读取内部作用域的变量 2)保证了全局作用域不被污染,因此不再需要立即执行函数表达式的使用 3)也防止了变量的重复声明 3 箭头函数 箭头函数也是ES6中非常重要的一个变化点。
函数命名冲突 文件依赖顺序 模块雏形时代 2006年,ajax的概念被提出,前端拥有了主动向服务端发送请求并操作返回数据的能力,传统的网页向“富客户端”发展,出现了简单的功能对象封装。...(不污染模块外的任何代码) 如何唯一标识一个模块? 如何优雅的把模块的API暴漏出去?(不能增加全局变量) 如何方便的使用所依赖的模块?...模块化的规范 1、CommonJS 2009年Nodejs发布,采用 CommonJS 模块规范。 特点: 每个文件都是一个模块实例,代码运行在模块作用域,不会污染全局作用域。.../libs/require.js"> 特点:浏览器直接运行无需编译,异步加载,依赖关系清晰 3、CMD/SeaJS CMD规范专门用于浏览器端,同样是受到Commonjs的启发,国内(...ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。 邀请人:一起重学前端
ShadowRealm ShadowRealm 是一个 ECMAScript 标准提案,旨在创建一个独立的全局环境,它的全局对象包含自己的内建函数与对象(未绑定到全局变量的标准对象,如 Object.prototype...外界不能访问函数内的变量,同时由于作用域的隔离,也不会污染全局作用域,通常用于插件和类库的开发,比如webpack打包后的代码。.../src/index.js"]();})();但 IIFE 只能实现一个简易的沙箱,并不算一个独立的运行环境,函数内部可以访问上下文作用域,有污染作用域的风险。...,但是对于全局对象,仍然可以访问并篡改,有污染全局的风险。...任何在沙盒内声明或者修改的变量都不会影响到全局作用域,同时,全局作用域下的变量在沙盒内也是不可见的)// 创建一个沙盒对象,这个对象里面的属性和全局作用域不同步,避免沙盒内代码影响外部环境const sandboxProxy
局部作用域 定义:局部作用域的意思就是,变量只能在它的代码块或者函数内部访问,而不能在外部访问,局部作用域的变量在函数或代码块执行完后会销毁,不会影响全局作用域变量。...:局部作用域变量不会影响外部代码,防止变量污染全局作用域。...全局作用域 定义:全局作用域指的是变量或函数在整个程序的任何地方都可以访问,且不会被局部作用域所限制。 全局作用域的特点 声明在任何函数或代码块外部的变量,默认具有全局作用域。...全局变量在整个程序执行期间都存在,不会被自动销毁(除非手动删除或页面刷新)。 全局作用域的变量会成为 window(浏览器环境)或 global(Node.js 环境)对象的属性。...指的是当一个变量在当前作用域找不到时,js会沿着作用域的层级结构向上查找,直到找到该变量或到达全局作用域。 作用域链的工作原理 当访问一个变量时,JavaScript 先在当前作用域查找。
减少全局变量污染,前端开发的初期,我们都在为全局变量而头疼,因为经常会触发一些难以排查且非技术性的 bug。当一些无关的代码一不小心重名了全局变量,我们就会遇到烦人的“命名空间污染”的问题。...缺点 污染了全局变量 模块之间的关系模糊 对象封装 其实就是把变量名塞的深一点。。。 ?...特点 以文件为一个单元模块,代码运行在模块作用域内,不会污染全局变量 同步加载模块,在服务端直接读取本地磁盘没问题,不太适用于浏览器 模块可以加载多次,但是只会在第一次加载时运行,然后在加载,就是读取的缓存文件...一个模块就是一个单例,或者说就是一个对象 代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。...不会污染全局作用域; 模块脚本自动采用严格模式,不管有没有声明use strict 模块之中,可以使用import命令加载其他模块(.js后缀不可省略,需要提供绝对 URL 或相对 URL),也可以使用
领取专属 10元无门槛券
手把手带您无忧上云