山东省建设厅注册中心网站,北京seo代理计费,做烘培的网站有哪些,嘉兴云推广网站export和module.exports
(需要前面的export没有“s”,后面的module.exports 有“s”)
使用两者根本区别是 **exports **返回的是模块函数 **module.exports **返回的是模块对象本身#xff0c;返回的是一个类 使用上的区别是exports的方法可以直接调用module.exports需要new…export和module.exports
(需要前面的export没有“s”,后面的module.exports 有“s”)
使用两者根本区别是 **exports **返回的是模块函数 **module.exports **返回的是模块对象本身返回的是一个类 使用上的区别是exports的方法可以直接调用module.exports需要new对象之后才可以调用 在js编程中经常会有模块的导出导入涉及到一些导入导出关键字
导出关键字 module.exportsexportsexportexport default导入关键字 require const xxx require(模块名)import import { xxx } from 模块名import xxx from 模块名import xxx1, {xxx2, xxx3,...} from 模块名import * from 模块名
因为在实际开发中经常会混淆这些用法所以想要弄清楚这些的区别让自己明白自己到底在写什么。本文作为学习笔记输出。 模块规范
JS模块化编程分了两种规范CommonJS模块规范和ES6模块规范。
CommonJS模块规范 —— CommonJS规范中以module.exports导出接口以require引入模块ES6模块规范 —— ES6标准规范中以export指令导出接口以import引入模块
在Node.js编程中Node模块系统遵循的是CommonJS规范。
CommonJS模块规范
CommonJS规范规定: 每个js文件就是一个模块有自己的作用域。 在一个文件里面定义的变量、函数、类都是私有的对其他文件不可见。 如果要暴露给其他程序需要以module.exports导出接口以require引入模块。
module.exports 和 exports module.exports / exports: 只有 Node 支持的导出 模块导出的时候导出的是module.exports不是exports module.exports可以导出所有的类型。对象函数字符串、数值等。 每一个js文件通过node执行时都自动创建一个module变量和一个exports变量。 module变量代表当前模块。这个变量是一个对象同时module对象会创建一个叫exports的属性即module.exports该属性初始化的值是 {}是对外的接口。加载某个模块其实是加载该模块的module.exports属性。
//logtes.js
console.log(我是外部js,没有使用export)
console.log(module)执行node test1.js的打印结果 path: C:\\Users\\xxwang\\Documents\\pmms\\TS\\tsdemo\\day01, exports: {}, filename: C:\\Users\\xxwang\\Documents\\pmms\\TS\\tsdemo\\day01\\logtes.js,loaded: false, children: [], paths: [ C:\\Users\\xxwang\\Documents\\pmms\\TS\\tsdemo\\day01\\node_modules, C:\\Users\\xxwang\\Documents\\pmms\\TS\\tsdemo\\node_modules, C:\\Users\\xxwang\\Documents\\pmms\\TS\\node_modules, C:\\Users\\xxwang\\Documents\\pmms\\node_modules, C:\\Users\\xxwang\\Documents\\node_modules, C:\\Users\\xxwang\\node_modules, C:\\Users\\node_modules, C:\\node_modules ]
} Process finished with exit code 0默认exports变量是对module.exports的引用即exports和module.exports指向同一个内存块。 这等同在每个模块头部有一行这样的命令。
var exports module.exports;
当通过exports去改变内存块里内容时module.exports的值也会改变当通过module.exports去改变内存块里内容时exports的值也会改变当module.exports被改变的时候exports不会被改变当exports被改变的时候module.exports不会被改变
所以exports属性的出现应该可以直接向exports对象添加方法从而方便对外输出模块接口。不过当module.exports改变时exports与module.exports也就断开了链接所以最好不要采用这种方式统一采用module.exports方式。
// module_export_demo.js
module.exports.a 100
console.log(log1: exports.a) // log1: 100exports.a 200;
console.log(log2: module.exports.a) // log2: 200module.exports hello
console.log(log3: JSON.stringify(exports)) // log3: {a:200}
复制代码module.exports可以导出所有的类型。对象函数字符串、数值等。 语法示例
// module_export_demo2.js
var x 5var str hellovar addX function (value) {return value x
};class Point {constructor(x, y) {this.x x;this.y y;}toString() {return ( this.x , this.y );}
}// module.exports.x x
// module.exports.str str
// module.exports.addX addX
// module.exports.Point Pointmodule.exports {x: x,str: str,addX: addX,Point: Point
}// require时对比下两种方式x的值到底取哪个
exports {x: 10,
}
复制代码require
requirer用于加载模块是node的一个全局方法使用非常简单
const xxx require(模块名)
复制代码读入并执行一个JavaScript文件返回模块的exports对象。如果没有发现指定模块会报错。
require方法接受以下几种参数的传递
原生模块如http、fs、path等相对路径的文件模块如./mod或../mod绝对路径的文件模块如 /pathtomodule/mod第三方模块如koa等
在模块目录中通常有一个package.json文件并且将入口文件写入main字段 // package.json{ name : some-library,main : ./lib/some-library.js }
复制代码require发现参数字符串指向一个目录以后会自动查看该目录的package.json文件然后加载main字段指定的入口文件。 如果package.json文件没有main字段或者根本就没有package.json文件则会加载该目录下的index.js文件或index.node文件
因为模块导出的实际是module.exports所以require只能看到通过 module.exports 导出的内容看不到通过exports导出的内容。它相当于module.exports的传送门module.exports后面的内容是什么require的结果就是什么对象、数字、字符串、函数...再把require的结果赋值给某个变量。 针对上面的 module_export_domo2.js 文件引入模块示例
// node require_demo2.js
const demo2 require(./module_export_demo2)console.log(demo2.x) // 5 也证明了引入的是module.export的内容
console.log(demo2.str) // hello
console.log(demo2.addX(15)) // 20 5 15 let point new demo2.Point(3, 4)
console.log(point.toString()) // (3, 4)
复制代码require 是运行时的其参数可以是表达式
let value 2
const demo2 require(./module_export _demo value)
复制代码require函数加载模块 require函数加载模块顺序按照其在代码中出现的顺序 require函数加载模块是同步的只有加载完成才能执行后面的操作 require函数加载的模块是被输出的值的拷贝不会受到模块内容变化影响 // module_export_demo3.jsvar counter 3;function incCounter() {counter;}module.exports {counter: counter,incCounter: incCounter,};
复制代码const demo3 require(./module_export_demo3)console.log(demo3.counter); // 3demo3.incCounter();console.log(demo3.counter); // 3
复制代码counter输出结果说明module_export_demo3模块内部的变化就影响不到counter了 模块第一次被加载时会执行一次后续被加载时不会再执行都是从缓存中获取的 // module_export_demo3.js
console.log(hello)
module.exports wrold
复制代码const demo3 require(./module_export_demo3)
const demo3_1 require(./module_export_demo3)
const demo3_2 require(./module_export_demo3)
const demo3_3 require(./module_export_demo3)
const demo3_4 require(./module_export_demo3)
const demo3_5 require(./module_export_demo3)
console.log(demo3)
console.log(demo3_1)// hello
// wrold
// wrold
复制代码hello只会被打印一次说明console.log(hello)语句只执行了一次module_export_demo3.js只被加载了一次。
ES6模块规范
ES6发布的module并没有直接采用CommonJS甚至连require都没有采用也就是说require仍然只是node的一个私有的全局方法module.exports也只是node私有的一个全局变量属性跟标准什么关系都没有。 ES6模块规范是在创建JS模块时export 语句用于从模块中导出函数、对象或原始值以便其他程序可以通过 import 语句使用它们。
export 和 export default
ES6模块导出有两种方式export(命名导出) 和 export default(默认导出)。 在导出多个值时命名导出非常有用。在导入时必须使用相应对象的相同名称。但是可以使用任何名称导入默认导出。
export语法介绍
// 导出单个特性
export let name1, name2, …, nameN; // also var, const
export let name1 …, name2 …, …, nameN; // also var, const
export function FunctionName(){...}
export class ClassName {...}// 导出列表
export { name1, name2, …, nameN };// 重命名导出
export { variable1 as name1, variable2 as name2, …, nameN };// 默认导出
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };// 导出引入模块的导出值
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export * from …; // 导出引入模块的所有导出值不包括模块的默认导出值
export { default } from …; // 导出引入模块的默认导出值
复制代码export与export default均可用于导出常量、函数、文件、模块等通过export方式导出在导入时要加{ }export default则不需要在一个文件中export可以有多个export default仅有一个大部分风格建议模块中最好在末尾用一个export导出所有的接口
export 1 // 这种写法错误// 正确的写法
const value 1
export { value }// 或者
export const value 1// 或者
const value 1
export default value// 或者
export default 1
复制代码export default是别名的语法糖这个语法糖的好处在是
import的时候可以省去花括号{}。import的时候, 可以起任何变量名表示引入变量
所以如果import的时候你发现某个变量没有花括号括起来除了* 号是因为该变量是通过export default 导出的。
// d.js
// 导出函数
export default function() {}// 等效于
// function a() {};
// export {a as default};复制代码import a from d.js // a 是 {defalut as a}的替代写法。
复制代码所以使用export default命令为模块指定默认输出这样就不需要知道所要加载模块的变量名。
// a.js
let sex boy;
export default sex //sex不能加大括号 等价于 export {sex as default}
复制代码本质上a.js文件的export default输出一个叫做default的变量然后系统允许你为它取任意名字。 自然default只能有一个值所以一个文件内不能有多个export default。
// b.js
import any from ./a.js
import any12 from ./a.js
console.log(any, any12) // boy,boy
复制代码import
require 和 import是完全不同的两种概念。require是赋值过程import是解构过程 const xxx require(模块名) import { xxx } from 模块名
import是编译时的, 必须放在文件开头否则会报错import后面跟上花括号的形式是最基本的用法花括号里面的变量与export后面的变量一一对应。
import {a} from ..
复制代码支持给变量取别名。因为有的时候不同的两个模块可能有相同的接口可以给这个变量取一个别名方便在当前的文件里面使用。
import {a as a_a} from ..
复制代码import介绍语法
import defaultExport from module-name;
import * as name from module-name;
import { export1 } from module-name;
import { export1 as alias1 } from module-name;
import { export1 , export2 } from module-name;
import { foo , bar } from module-name/path/to/specific/un-exported/file;
import { export1 , export2 as alias2 , [...] } from module-name;
import defaultExport, { export1 [ , [...] ] } from module-name;
import defaultExport, * as name from module-name;
import module-name;
var promise import(module-name); // 动态模块加载返回的是一个promise对象
复制代码Node为何支持export / import
我们经常会看到在node中也会用export / import这是什么呢 我们在node中使用babel支持ES6仅仅是将ES6转码为ES5再执行import语法会被转码为require。因为目前所有的引擎都还没有实现export / import。 如何让Node.js支持ES6的语法具体参考在node环境中支持ES6代码
// ES6语法
import {a} from ./demo.js
// 转码ES5后
var _demo require(./demo.js)
复制代码这也是为什么在使用module.exports模块导出时在引入模块时使用import仍然起效因为本质上import会被转码为require去执行。
总结
CommonJS规范中建议尽量都用 module.exports 导出然后用require导入 ES6规则中大部分风格建议模块中最好在末尾用一个export导出所有的接口
module.exports / exports: 只有 Node 支持的导出require: Node 和 ES6 都支持的引入export / import : 只有ES6 支持的导出引入