大家好,我是毛小白,本文是关于前端混淆知识点的第一题,阅读全文大约需要3分钟。我想大家在日常工作中做过很多项目,敲过很多代码,但是有的时候很多基础知识点都非常模糊,或者处于一头雾水、一头雾水的状态,当然也包括我。现在一个项目的周期很短,借用我们老大的一句话(应该看不到):大部分客户都不知道自己要什么,你只需要抓紧时间(周五见,没有问题收敛)让他去体验它,他知道他应该想要什么。所以为了赶进度,大部分工作都在ctrl+c+ctrl+v。这样一来,很多基础知识就会被遗忘甚至忽略,但往往问题出在这些小细节上。所以我想写一个【困惑系列】。在自己学习的过程中,我会整理分享一些前端开发过程中容易混淆或者记错的知识点,分享给大家。容易混淆的可以在评论区留言。知识点,一起进步,一起学习。那么下面开始【困惑系列】第一个问题:module.exports、exports、exports有什么区别?这三个东西其实是两个概念的区别:先看一张表:specificationnameexportkeywordsimportkeywordsrenamevariablescollectiveexportcommonjsmodule.exports/exportsrequire{A:B}不支持esmexportimportas*asxxx其实还是比较清楚的,不同的规范使用的关键字和特性是不同的,我们通过这些关键字来区分我们在什么环境下编写的代码。nodejs(webpack,babel)->commonjs,browser(vue的脚本标签或html中type="module"的脚本标签)->esm.module.exports和exports是一组,都是基于commonjs规范的。export是基于es6的esm(ECMAScriptModules)规范。CommonJS规范:CommonJS规范是为解决JavaScript的作用域问题而定义的一种模块形式,它允许每个模块都在自己的命名空间中执行。该规范的主要内容是模块必须通过module.exports导出外部变量或接口,并通过require()将其他模块的输出导入当前模块作用域。示例://moduleA.jsmodule.exports.double=function(value){returnvalue*2;}//moduleB.jsvar{double}=require('./moduleA');varres=double(4);console.log(res)//8为了方便起见,module.exports在某些情况下可以简写为exports。其实exports一开始就是对module.exports的引用。module.exports===exports//true所以上面的moduleA.js可以像这样省略module//moduleA.jsexports.double=function(value){returnvalue*2;}//moduleB.jsvar{double}=require('./moduleA');varres=double(4);console.log(res)//8当module.exports后面跟着赋值语句时,module.不能省略,为什么?我们一开始看module.exports等于exports。我们可以看到在文件的开头有这样一段代码:module.exports={};//开头是一个空对象很容易理解letexports=module.exports;console.log(module.exports===exports)//true所以给exports对象添加任何新的属性{}其实就是给module.exports添加属性,因为我们知道node中的对象也是引用类型。如:exports.double=function(value){returnvalue*2;}exports.PAI=3.1415926535897932384626//233,我能背这么多位~exports.add=function(a,b){returna+b;}危险!给exports赋值就不行module.exports={};//好理解,一开始是个空对象letexports=module.exports;//给exports赋值会切断与module的连接.exports//这样子,别这样~!exports={name:'zhangsan'}//或者这个不要做~!exports=functionname(a){}//或者这个不要这样~!exports=3.1415926535897932384626console.log(module.exports);//打印:{}返回初始{}值console.log(exports);//打印:3.1415926535897932384626console.log(module.exports===exports);//false不管你走独木桥还是我走我的阳关路。如果要使用赋值导出,可以这样导出一个对象://moduleA.jsmodule.exports={name:'法外狂人张三',age:'19',wife:'隔壁小红'}//moduleB.jslet{name,wife}=require('./moduleA');console.log(name,age)//隔壁法外疯子张三这样小红就可以保证module.exports可以拿到价值。如何用(:)符号重命名commonjs中导出的变量:let{name,wife:girlfriend}=require('./moduleA');esm(ECMAScriptModules)规范现在我们在编写vue或react项目中熟悉的es6模块规范。esm是一个标准,用于将javascript程序拆分为单独的模块并按需导入它们。不同于webpack和babel,esm是javascript的标准函数,在浏览器和nodejs中都已经实现了。使用esm的好处是浏览器可以优化加载模块,比使用库更高效。模块变量的导入导出是通过import和export语法实现的:在commonjs中使用require和modelue.exports导入导出模块,在esm中使用import和export导入导出。esm的导出支持:let、var、const、function、class等都是正确的导出方式:varperson={name:'猫小白',text:a,}export{person,}exportfunctionshowAge(){console.log(person.age);}exportletcity='Chengdu'exportconstPAI='3.141592653'注意:export命令规定了对外的接口,必须和模块内部的变量建立一一对应关系.//错误1??export3.14;//错误2varapi=3.14;导出接口;这两种写法都是错误的,因为export后面直接跟着一个具体的,外部是无法通过具体的标识符(变量)获取到这个值的。exportdefault默认导出和commonjs规范更高级一些。Esm默认提供了导出的方式。exportdefault后面可以直接跟:variable,specificvalue,function,calss。//正确leta='张三';exportdefaulta//正确exportdefault3.14exportdefaultfunction(a){returna*a}//正确letsum=function(a,b){returna+b}exportdefaultsum//正确函数calc(a,b){returna+b}如何重命名exportdefaultcalcESM中提供了as关键字来重命名导出的变量,防止变量名重复。从“./moduleA.js”导入{妻子作为女朋友};当你想将所有方法或变量导出为指定变量时,可以使用import*asmodfrom"xxxx"import*astoolfrom"./moduleA.js";console.log(tool.API)//3.141592ESM模块规范规定在html脚本标签中设置type='module'可以编写ESM模块代码,包括导入函数:同上。篇幅有限,还有很多地方没有写到,但足以区分两者。接下来我应该写什么?欢迎大家评论留言或指出错误~,谢谢!请大家不要忘记点赞、评论、收藏我。过往亮点:1.【宝珍】我的第一次webpack优化,首屏渲染从9s到1s2。什么是迭代器?Generator跟它有什么关系
