node基础知识部分小记

    技术2025-04-02  14

    Day01 1.严格模式 1)变量必须写var 2)this不能指向window 3)eval有独立的作用域 使用目的:为了后面ES6做铺垫 2.json对象 1)Unexpected token ’ in JSON at position 1 json.parse()参数里的json数据,格式不对 2)JSON.parse() json字符串转js对象/数组 3)JSON.stringify() js对象/数组转json字符串 4)JSON字符串 和JS对象的区别: json字符串数据里,key必须双引 js对象,key随便 3.Object.assign(目标对象,待合并对象1,待合并对象2,…) 作用:把从第二个参数里的所有对象的key+value赋值到第一个参数对象上 4.Object.create() 创建对象 Object.create(以哪个对象为基准,额外添加的key和value{ writable:false,//(默认不写是false)false此属性值不可以被更改 configurable:false,//(默认不写是false)false判断属性能否被删除 enumerable:false,//(默认不写是false)false不可以被for-in遍历 }) 注意:1.参数1不会受影响 2.此方法在参数1为基准,额外添加新的属性 3.可以对新添加的属性,进行权限控制 4.基准对象是扩展在新建的对象的__proto__原型属性上的 使用: 1)以另外一个对象为基准,创建一个新对象时,使用 2)如果想对某个属性进行权限控制,使用 5.Object.defineProperty() 给现有的对象 Object.defineProperty(目标对象,新增的key名,新的key的配置) 默认不能修改不能删除不能遍历 作用:可以给现有的对象添加属性,并控制权限,或对现有的属性,添加控制权限 6.set和get使用注意 1)不要在get里触发此属性的取值:不然会出现死循环 2)不要在set里触发此属性的赋值:不然会出现死循环 可以使用中转变量(名字随便起) 来避免上面的问题 set和get就是想要自己实现一个取值和赋值的过程,不用系统默认的 7.如果算数运算计算错误: 会返回 NaN 比如: “123省道” * 2 就是NaN null + 10 JS引擎会把null 隐式转换为0 (虚值) 单纯的遍历: forEach() 返回处理后的值的数组: map() 过滤: filter(),回调函数里return的是判断条件 累计运算: reduce() 8.面试题: // 数组的方法, 在遍历时, 是不会修改原数组的 // 但是, 如果这个值是一个对象/数组 (引用类型), 是可以去改变对象/数组里的值 let myArr = [123, {age: 18}]; myArr.map(function(val, ind){ if (ind === 1) val.age = 29; // 如果只有一行代码, 可以省略{} // val = 999; }) 9. bind使用 // 总结: (重点3) // call / apply 会马上触发函数执行一次, 对传入的对象绑定属性 // bind 不会马上触发函数执行, 会返回一个功能一模一样的函数(并且内部this已经被改变了), 但是这个函数还没有执行(所以obj上还没有被添加属性), 需要自己手动调用一次

    10.块级作用域 // 1. 在函数内使用var声明的变量, 是拥有函数级作用域 // 2. 在大括号内(语句块)用let声明的变量, 只能在{}内使用, 块级作用域 // 3. 如果在函数内使用let声明变量, 也是只在函数内有效 作用域影响的是取值方式

    let好处 // 1. let在for循环时, 不会泄漏到全局作用域(函数之外的地方, for循环块作用域) // 2. let声明的全局变量, 不会添加到window身上

    12.let注意事项 // 1. let不存在变量提升(暂时性死区) // 2. 同一个作用域下let的变量名不可以重复

    Day02 1.const使用 声明的变量只能给初始值 此变量不能被重新赋值 2.结构赋值 优化赋值的过程 注意模式要对应 数组的结构赋值:靠下角标对应 对象的结构赋值:靠key对应 3.模板字符串 简化标签的动态生成,简化拼串的过程 4.Array.from 把伪数组转成真数组 5.对象的简化写法 当key和value变量名同名时,只写key 当key对应的value是一个函数的话。可以省略:function 6.属性名表达式 obj[‘address’]这种可以添加或取值 如果key是一个变量,必须使用属性名表达式的形式 keys提取对象所有的key,并返回数组

    Day03 1.箭头函数 箭头函数()=>为了优化回调函数/匿名函数的写法,其实就是把function换成=> 如果箭头函数的形参只有一个,可以省略小括号 函数体内只有一行代码,可以省略大括号,并且会返回这行代码的值 不能被用作构造函数不能用new去访问 箭头函数没有自己的this不能用call、apply、bind修改他的指向,this指向了外层函数作用域this的值 箭头函数内不能使用arguments,而要使用剩余参数运算符 口诀:ES5:function this默认指向函数的调用者 ES6 箭头函数 htis指向外层函数级作用域的this值 2.函数形参上的默认值 当形参的值是undefined时,会被默认值覆盖掉 3.剩余参数运算符 可以接受剩余的参数用法 4.展开语法 把数组/伪数组/对象,进行展开,可以直接插入到另外一个的新数组/对象中去 作用:一般用于复制数组 5.Symbol Symbol()调用一次,产生一个匿名的,唯一的值, 一般用于给对象添加唯一属性 一般使用变量来接收Symbol的值来进行使用 Symbol的描述符,一般用于描述和注释作用 6.Set容器 无序不重复的value集合体 一般用于去除重复元素 7.Map集合 无序 不重复的 key,value集合体 key的类型可以是任意类型,不像Object对象的key只能是字符串,一般用于key类型是非字符串的时候 8.Iterator接口 Iterator是一个抽象的概念,具体使用for…of,而for…of底层是Symbol.iterator属性 只要拥有了Symbol.iterator属性的对象,都可以被for…of进行遍历 所以,统一了接口访问的规则,所以数组、字符串、HTMLCollection等卡伊任意的互相转换 Iterator接口天数就有的,可以直接调用for…of的类型有: Array String Set Map HTMLCollection NodeList(qusterAll) arguments

    Day04 1.给Object不是Iterator接口,给Object添加了Symbol.iterator属性 Symbol.iterator属性 2.Generator函数 使用 function*函数名{},和普通函数的区别:调用 需要配合next()方法配合Generator函数的执行 遇到yield函数就暂停,把yield后面的值,返回给next()调用的地方 每次调用next()都会从上一次yield暂停处,继续执行 3.Promimse 目的:取代回调函数 异步操作的管理者,异步操作的容器 格式: new Promimse((resolve,reject)=>{ //执行一些异步的操作 异步操作成功,调用resolve }); promise.then(data => { // 使用then方法接收 异步成功的结果 console.log(data); }).catch(err => { // 使用catch方法接收 异步报错的结果 console.error(err); }) 三种状态 pendding状态 初始化状态 调用reject()后,当前Promise状态为tejected状态:失败状态 调用resolve()后,当前Promise状态为fulfilled状态:成功状态 Promise.all 作用: 可以用于把多个Promise对象合并成 一个大的promise对象使用 而且 同时执行多个Promise对象的操作,可以按照顺序返回结果 如果其中有某个小的Promise报错,大的Promise就会报错不会触发then,直接跳转到catch Promise.all([p1,p2,p3]).then(res=>{ // res结果是一个数组 每个元素 都是小的Promise的结果 }); 4.async 函数 async 是 Generator的语法糖 await 是 yield的语法糖 async function gen(){ let result = await fn(); console.log(‘上一步fn结束,返回结果’+result); } function fn(){ return new Promise((resolve,reject)=>{ setTimeout(function(){ resolve(‘123’); },2000) }) } gen(); async是一个异步操作的函数,需要等待主线程执行完毕后,再来调用async函数内的执行,跟代码的执行顺序无关 被async修饰的函数,一直会return一个promise对象,会把函数内return的具体结果,当做resolve()赋予给promise对象上

    Day05 1.什么是node? Node既是一个环境,也是语言(node.js),因为node实现了ECMAScript标准,与js的语法标准基本一致,node可以独立执行js代码,脱离了浏览器,所以window中没有window,也没有document,但是对console等进行了实现,所以可以继续使用 node特点:单线程,跨平台,非阻塞,事件驱动,回调函数 2.为什么学node 方便和后端工程师沟通,数据库的使用 3.怎么学? 安装node环境,node-v在cms中执行,查看是否允许成功 4.node的全局变量 global:相当于window 所以全局的this是global __filename:获取文件名的绝对路径 __dirname:获取文件所在文件夹的绝对路径 5.进制 6.Buffer

    Day06 1.async函数的执行问题 主线程执行完以后,才会继续从awati左侧开始往下执行 2.fs模块的功能方法 带Sync的是同步方法,不带的是异步方法,需要配合回调函数 我可以移动文件+重命名 rename 重命名 unlink 删除文件 mkdir 创建文件夹 readdir 读取文件夹下所有的文件+文件夹 名字 rmdir 删除文件夹 fs.stat() 返回一个信息对象 调用is File() 获isdir() 3.异常捕获 异步操作配合回调函数捕获异常 同步操作配合try…catch捕获异常 4.events模块 自定义事件,自定义触发 on()用于监听事件 以及对应触发的回调函数 emit() 用于触发事件 给上面的回调函数传参 once() 只能触发一次 5.node模块化 模块:封装的.js文件,在node中每个.js就是一个独立作用域的模块 一个.js文件就是一个模块 使用:1.定义模块,并导出 2.明确模块的标识符,3.导入 导入模块后实际上就得到了一个函数、对象 可以调用导入模块中的一些属性和方法 6.模块为什么是独立作用域:因为在运行时,会给每个模块.js文件套住一个function 7.npm的使用 模块:node中把每个.js文件都认为是一个模块,无论是自己封装的.js文件还是业务.js文件 模块包:就是一个文件夹,里面包含很多模块.js文件 8.npm的简介和作用 Node Package Manager,上传,下载,查询,删除我们需要的模块包 因为在开发项目时,需要引入一些,其他程序员写入的模块包 在node6.0以后的版本中,node+npm是打包下载安装的,就是你安装了node环境,npm也自带了 9.npm的使用过程 1.明确模块包的名字 百度上搜,书上看的 2.去npmjs.com网上/官网镜像上,确认包的名字及版本号,确认安装的命令 3.cmd切换到目标工程目录文件夹下,明确此目录下是否有package.json 此处可选(如果有package.json)此步骤跳过,没有的话,必须运行 cmd中:npm init,让你录入一些参数,包名不能是中文,其他回车 4.在cmd中执行第二步,找到的安装模块包命令,让npm开始现在此模块安装到昂前工程中 此处可选(明确npm镜像地址,最好淘宝)此步骤跳过,没有的话,速度慢 npm config set registry http://registry.npm.taobao.com npm config list 查看npm镜像地址 查看npm的配置信息 5.查看当前工程中,多出来的东西 *package-lock.json 锁定最大版本号 *node_modules 所有的模块包 10.下载好的npm在业务中如何调用 const md5 =require(‘md5’); console.log(md5(‘111’));

    Day07 1.对packega.json里的补充 scripts:配置的npm下的自定义命令 npm run 命令名 cmd中真正执行的是value中的值 dependencies:线上环境需要用到的包 devDependencies:线下环境开发需要用到的包 2.npm常用命令 // npm -v查看npm版本号 // npm init 初始化package.json文件 // npm init -y都是要默认值省略输入的过程 初始化package.json文件 // npm i/install xxx安装某个模块包 模块包可以同时安装多个 中间用空格隔开 // npm i xxx @版本号 指定版本号,但是要注意版本号 必须在npmjs.com上能找到 // npm i xxx --save (–save可以写作包名的左边或右边 代表记录到dependencies,默认不写的时候就是) // npm i xxx --save-dev (代表记录到devDependencies) // npm i xxx -g 把带命令行的模块安装到电脑中,可以直接使用一些命令 就是可以直接在终端使用命令的工具包 代表把模块包安装到全局node_modules,切记只有带命令行的模块包才可以安装到全局模块使用 如果电脑没找到AppData/Roaming 可能隐藏了 普通安装的模块包,没有全局的概念 只有父级概念 当前工程中没有找到require要引入的包名 就会一直向父级查找,直到找到根目录,如果没有就报错 -g 全称 global // npm i/install 什么包名都不写 这时 npm会从当前cmd终端所在文件查找package.json 吧package.json中记录的包都下载下来 // npm s/search 在官方镜像下可以搜索包名 // npm uninstall/remove xxx 删除某个包 // npm config list 查看npm 的配置列表 3.使用npm下载的包 const mdt = require(‘md5’);无需写相对路径,require会自动找node_modules 4.npm自定义命令 5.导入模块、模块包的区别 注意模块包文件夹的入口.js是谁,具体看package.json里的main属性对应的就是入口文件 6.概念 ip地址:在全球的互联网中,每个能接入互联网上网的设备,都有一个唯一的不重复的ip地址,来标记他的位置,公网,外网 局域网:每个家庭,单位,网吧,都会至少有一个出口ip,在这个ip下由路由器来连接多台设备,统一使用这个出口ip上网,内网,局域网内有内网的ip地址,只能在内网中互相访问 端口号:用于区分一台电脑中的不同的服务 浏览器中显示的一切东西都来自于地址指向的服务器上 浏览器是一个查看内容的工具,本身并不能存储网页、js、css等静态资源 静态资源是靠url地址来访问目标文件,把内容返回到浏览器,由浏览器渲染给用户 浏览器访问的一般都是web网页服务,web网页服务:Apache,Tomcat,Node+http 7.Node+http模块搭建了网页服务 // 在node的环境上,使用node.js借助http模块,来搭建web网页服务 // 1.引入http 核心模块 const http = require(‘http’); // 2.调用方法生成web网页服务的对象 const server = http.createServer((requset,response)=>{ // 3.此回调函数当浏览器请求这个node的web网页服务时会触发函数执行 console.log(‘浏览器发起了请求’); response.end(‘hello’);//给浏览器响应(返回)一个内容,并结束本次响应 }); // 4.给web网页服务分配端口号 server.listen(3000);//范围1024-65535(1024以前的需要管理员权限)

    // 5.启动web网页服务 // 切换目录,node xxx.js // 此终端不能关闭,此时web网页服务已经启动起来了,而终端里一直等待浏览器来访问web网页服务

    8.请求和响应 先要理解前台和后台: 前台:浏览器 后台:提供服务的服务器 前台发起请求到后台,后台返回响应 注意:一次请求对应一次响应 所以每次触发node里的createServe回调,就是来了一次请求 res.end()代表结束本次响应 end要写在最后 node xxx.js 启动

    Day08 1.url的定义 // 例如 http://106.13.114.114/biyao/public/static/image_source/goods_loop_img/Koala.jpg&firstid=901&secondid=100#hello // url组成: // 1)http:// http协议 规则(超文本传输协议) // 2)// … : 之间这部分叫ip/域名 确定要访问的那台服务器地址 // 3):3000 端口号:确定访问电脑里的什么服务 // 4)端口号以后,/biyao/public/static/image_source/goods_loop_img/ 路径部分 作用:去服务器端,在3000端口的服务下,去寻找这个路径下的资源 // 5)Koala.jpg 文件名 确定资源的文件名,可以省略 // 6)问号后 firstid=901&secondid=100 要传递的提交的参数,传给前面这个url(后端) // 7)#hello 附加上额外的参数 一般只用在前端上 vue中的路由就是锚点连接 2.url模块的使用: 前端浏览器进行请求时,会传给后台一些参数,再请求对象上req.url里面就是前端发起请求时的url地址,可以使用url模块里的parset方法格式化,去除query(?后面)和pathname(路径参数) 3.get传参 4.传递路径 5.path模块:处理文件+文件夹路径的作用 提前根路径的名字,文件夹路径的名字,完整的文件名,扩展名 6.静态资源的访问 vscode内置web网页服务,为什么写对路径就能返回对应文件的内容 静态资源文件:.html .js .css .png 等文件,都叫静态资源的文件,一般是要把内容返回给浏览器,让浏览器以对应的规则进行解析 7.后台要设置响应头里的Content-type的值,Mime类型 作用:告诉浏览器我要给你返回的内容类型 注意:图片因为不是中文或字符串,而是二进制数据流,所以读出的时候不要转成uft-8,而且还要设置Content-type,告诉浏览器如何解析图片 8.http协议:是一种规则,客户端/浏览器 ----服务器之间传输数据的方式,按照http协议的规则来传输 超文本传输协议

    要学会在浏览器里查看请求报文和响应报文 9.请求报文 /* 1. POST /work/1.php HTTP1.1 请求方法,请求的路径 2. Host:www.wrox.com 域名 请求头 3. User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022) 浏览器标识信息 请求头 4. Content-Type:application/x-www-form-urlencoded 请求头 发给后台参数的样子就是,key=value&key=value 5. Content-Length:40 请求头 6. Connection: Keep-Alive 请求头 7. 空格 必须的 把参数和请求头分隔开 8. name=Professional_Ajax&publisher=Wiley&page=1 参数,请求体,写请求参数的地方 */ // 详解:第四行代表:请求时,发送的参数,将会以什么样的内容类型发送给后端 // 设置成application/x-www-form-urlencoded 请求头 发给后台参数的样子就是,key=value&key=value

    // 请求报文= 请求方法+请求路径+请求头+请求体(传递的参数,get在url上传参)

    10.响应报文 /* 1. HTTP/1.1 200 OK 响应状态码 2. Date: Fri, 22 May 2009 06:07:21 GMT 响应头 3. Content-Type: text/html; charset=UTF-8 响应头 告诉浏览器如何设置或解析一些数据 4. 空行 规定 把响应体的内容隔开 5. 第五行往下都是后台响应返回给浏览器的内容 res.end()返回的内容 / // 响应状态码:后台设置响应状态码,返回给前端去用 /* 1. 200: 客户端请求, 和服务器成功做出响应 2. 301: 重定向, 资源被重定向到一个***永久性***的地址上, 资源的原始url可能无法访问 3. 302: 重定向, 资源被重定向到一个***临时性***的地址上, 资源的原始url还在 4. 400: 语义错误, 无法被服务器理解, 请求参数有误 5. 401: 请求需要用户验证, 包含了 Authorization 证书, 但是被服务器拒绝了 6. 403: 服务器已经理解请求, 但是拒绝执行它 无权限 7. 404: 请求url不存在 (一般常见于请求路径拼写错误) 8. 500: 服务器遇到了一个未曾预料的请求, 一般出现在后台代码报错 9. 502: 网关或者代理服务器请求时, 从服务器接收到了一个无效响应 10. 503: 服务器过载, 当前无法完成响应, 拒绝客户端连接 11. 504: 网关或者代理服务器请求时, 等待响应超时了 */

    Day09 1.express的解决 内部是对http模块的二次封装,让我们编写一个web网页将变得非常简单 express采用路由的形式,可以用app.请求方法 使用:先确认npm的package.json包 2.路由结束 路由=路径=api接口 = url 后台编写不同的路由,边界 3.不同的请求方式 get push delete post 对应前端发起请求方法 4.get方式的传参 前端:http://127.0.0.1:3000?/stu?sno=10086; 后端:url模块的parse()方法,把参数提取出来 5.Rest Client 用vsCode下载插件来测试接口 还可以使用postman来替代插件 6.express默认错误的处理 express内部封装了一个错误提示的返回页面,当所有路由都不名字时,会返回一个错误提示的页面 7.路径传参 了解 可以通过url传参,隐藏后台参数名的暴露,提前在后台路由的路径中,设置对应位置的key的变量名,再调用匹配时,会从对应路径中取出value,统一放在 8.中间件的概念 1.自定义中间件函数: 使用中间件函数app.use(函数体) 2.静态资源中间件函数 express.static(指定静态资源文件夹) 浏览器发起请求时,请求分为两大类: 静态资源url,一般会以具体的文件名结尾,express配合express.static来返回静态资源 API数据接口,一般使用ajax来调用、form表单提交、Rest Client插件测试 后台就是app.get()等方法 3.路由中间件函数 express.router() 返回一个路由中间件函数 对象 router和app的功能是一样的,但入口文件只有一个.js,不能在listen了 分散api数据接口,分散管理,但是最后都要把模块引入到入口中,让express中

    Day10 // 前端传递get参数,后端用url模块 从query中取出 // 前端传cookie参数 后端用cookie-parser模块 集成的app中间件函数 从req.cookies中取出 // 浏览器调用document.cookie设置cookie的值,后端去设置浏览器的cookie的值res.cookie // 不要在url/请求头/响应头中使用中文,会变成urlencode编码 如果想要中文,可以放在响应体即res.send()中交给前端使用,响应体中的中文收,Content-type:mime类型;utf-8;

    Day11 1.formidable 作用:后端用于解析,前端使用表单form标签设置(enctype:multipart/foem-data)/ajax配合Conttent-type:multipart/foem-data

    Day12数据库操作 增删改查 CRUD read读取查询 1.插入语句 INSERT INTO 表名(字段) VALUES(对应的值) values后面可以跟多个 2.更新语句 UPDATE 表名 SET 字段=值,字段=值 where 条件 切记 一定要跟条件,不能整个表的此字段都会被更新掉 3.查询语句 SELECT 列名(字段) FROM 表名 where AND ORDER BY字段 LIMIT 4.删除语句 delete from 表名 where 条件 2.node的mysql模块 因为sql的操作应该由代码控制,而不是我们自己编写的sql语句来操作数据库,数据都是会返回到浏览器上的网页中,而且用户操作网页 为什么js不能操作数据库 因为暴露在浏览器上的一切都是危险的,所以不让大家把后端代码暴露在静态资源文件夹下,而且后端的代码都放在服务器上,没有服务器的用户名和密码是无法查看后台代码的 前后端分离 3.步骤 1.引用 2.填写信息,创建连接对象 3.连接数据库 4.nodejs执行sql语句 4.前后端分离的项目 浏览器发起请求 api路由接口 触发对应代码执行 执行sql语句 操作数据库 返回一个结果给浏览器前端 5.awaityo.js 同步代码捕获异常 try+catch(await会把异步的操作变成同步的代码) 但是try+catch有很多大括号,不想要这么多的大括号 1.异步操作需要配合Promise来使用才能使用awaitto.js 2.awaitto把promise对象穿进去 to方法会把成功或失败的成功,转成一个数组返回出来 成功[null,数据] 失败[错误对象,undefined]

    从0开始做一个项目 动机 分开: 1.模块 2.如果没签,先写静态页面,如果有后端,设计数据库表结构 首页模块设计表 14 省份表- 市区表- 地区表- 用户表- 购物车表- 搜索表-保存用户搜索过的文字 一级分类 二级分类 三级分类 轮播图数据表 促销活动表 订单表 看销量 返回3-4个分类每个分类返回3个排行榜数据 订单表 看评价的分数 返回8个商品,评价排序 首页模块表 为了下面铺设每一个大模块,先记录都铺设哪些二级分类,以及对应下属的东西 猜你喜欢-(记录你浏览过的商品,后端代码取出你这个用户浏览过的商品,再查询类似的给你返回) 分类页: 商品表,保存所有商品 商品推荐橱窗表 3.创建表 4.根据页面内容,来觉得需要哪些列 5.录入测试、正式数据 手动录入数据 寻找数据 省市区的数据,可以sql导入省市区的数据,会找到sql文件导入即可 研究任意语言的爬虫功能(nodejs,php,python,java),爬虫下来的数据。直接写到数据表里 6.编写接口 后台采用nodejs+express编写api数据接口 开发完接口,测试是否可以使用,用rest Client 插件+.http文件 Day14 前端cookie localStorage/sessionStorage 后端session token临时通行证 购物车 判断cookie里是否有值 无值就是未登录的状态 同级队列中,顺序和时间都不同,听时间的,时间短的先执行

    DAY16 1.本身是一个模块包,安装在global环境上,可以使用webpack命令打包 2.它需要运行在mode环境上,所以 2.打包配置文件 webpack.config.js在使用webpack命令的时候,会寻找当前终端目录里的 3.context:当前配置文件的所有相对路径都以他的值为基准出发,绝对路径不受影响 entry:入口文件 output:出口文件,打包后的文件输出到哪个路径下的哪个文件path,file module:加载器,识别不同后缀结尾的文件 plugins:插件配置项,插件里都需要new一下,传入插件的配置对象:让webpack拥有更多的能力 src下的东西都要被打包 static下的东西不会被打包 使用static下的静态资源,非打包,不需要import,直接使用路径即可 我直接使用路径不会被当成是模块来对待,直接认为是路径 let img2 = document.createElement(‘img’); img2.src = ‘./static/image/英短.jpg’ document.body.appendChild(img2); static应该直接写./,在本地开发环境可以,是因为dist出来正好看到了static目录,但是打包 解决方案:让webpack打包时,顺带把static复制到dist目录中

    17 前端得代码都可以在哪些web网页上访问? vscode/webpack-dev-server/express.static/http 5500/8080/3000/自定义端口 前端模块化开发 后端使用的模块化规范:ComminJS规范 导出:module.exports/exports.xxx 导入:require 大对象、解构赋值 前端使用的模块化规范:ES6 导出:export default/export 变量名 导入:import x from

    Processed: 0.013, SQL: 9