赞
踩
引用:
- //foo.js
- exports.foo="foo"
- //等同于
- module.exports.foo="foo"
-
- //bar.js
- const { foo } = require('./foo.js')
- console.log(foo);//'foo'
-
- 复制代码
- //foo.js
- exports={
- foo: 'foo'
- }
-
- //bar.js
- const { foo } = require('./foo.js')
- //reuqire 返回的是 module.exports 对象, 默认为 {}
- console.log(foo);//undefined
-
- 复制代码
commonJs 输出值拷贝
- /*************** a.js**********************/
- let count = 0
- exports.count = count; // 输出值的拷贝
- exports.add = ()=>{
- //这里改变count值,并不会将module.exports对象的count属性值改变
- count++;
- }
-
- /*************** b.js**********************/
- const { count, add } = require('./a.js')
- //在支持es6模块的环境下等同于
- import { count, add } from './a.js'
-
- console.log(count) //0
- add();
- console.log(count)//0
- 复制代码
esModule 输出值引用
- /*************** a.js**********************/
- export let count = 0;//输出的是值的引用,指向同一块内存
- export const add = ()=>{
- count++;//此时引用指向的内存值发生改变
- }
-
-
- /*************** b.js**********************/
- import { count, add } from './a.js'
-
- console.log(count) //0
- add();
- console.log(count)//1
- 复制代码
commonJs 输出的浅拷贝验证
- /*************** a.js**********************/
- const foo = {
- count: 0
- }
- //module.exports的foo属性为 foo 对象的浅拷贝,指向同一个内存中
- exports.foo=foo;
-
- window.setTimeout(()=>{
- foo.count += 1
- console.log('changed foo')
- },1000)
-
- /*************** b.js**********************/
- const { foo } = require('./a.js')
-
- console.log('foo', foo);//'foo',{count: 0}
- window.setTimeout(()=>{
- console.log('after 2s foo', foo);//'after 2s foo ',{count: 1}
- }, 2000)
- 复制代码
commonJs 输出时的危险操作
其实上个栗子中的 const { foo } = require('./a.js')
或者 const foo = require('./a.js').foo
写法是相当危险的。因为commonJs输出的值的拷贝,若后面在a.js中 对foo的内存指向作出改动,则不能及时更新。
我们将上面的栗子做个小改动:
- /*************** a.js**********************/
- const foo = {
- count: 0
- }
- exports.foo=foo; //此时foo指向 {count: 0}的内存地址
- window.setTimeout(()=>{
- //改变 foo 的内存指向
- exports.foo='haha';
- },1000)
-
- /*************** b.js**********************/
- const { foo } = require('./a.js'); //拷贝了 foo属性指向 {count: 0} 内存地址的引用
-
- console.log('foo', foo);//'foo',{count: 0}
- window.setTimeout(()=>{
- //看!并没有改变!
- console.log('after 2s foo', foo);//'after 2s foo ',{count: 0}
- }, 2000)
- 复制代码
改进:
- /*************** b.js**********************/
- const test = require('./a.js');
- //test 拷贝了 整个输出对象{foo:{count: 0} }内存地址的引用
- //当内存中的属性值发生变化时,可以拿到最新的值,因为指向的是同一片内存
-
- console.log('foo', test.foo);//'foo',{count: 0}
- window.setTimeout(()=>{
- //保证获取到的是最新的
- console.log('after 2s foo', test.foo);//'after 2s foo ','haha'
- }, 2000)
-
- 复制代码
进阶:
- /*************** child.js**********************/
- let foo = 1
-
- setTimeout(()=>{
- foo=2;
- exports.foo= foo
- },1000)
- exports.foo=foo
-
- /*******************index.js***************************/
- var test =require('./child');
-
- console.log(test.foo);// 1
-
- setTimeout(()=>{
- console.log(test.foo) // 2
- },2000)
- 复制代码
将child.js中的输出方式做一下改动,结果就变了。
- /*************** child.js**********************/
- let foo = 1
-
- setTimeout(()=>{
- foo=2;
- module.exports={foo};//注意:指向新内存 {foo:2}
- },1000)
- module.exports={foo}; //指向内存 {foo:1}
-
- /*******************index.js***************************/
- var test =require('./child');// 浅拷贝,指向的还是{foo:1}的内存,并缓存在内存中
-
- console.log(test.foo);// 1 //从缓存的内存中取值
-
- setTimeout(()=>{
- console.log(test.foo) // 1 //从缓存的内存中取值
- },2000)
-
- 复制代码
module.exports 等同于 export default 可以用 import 引入
CommonJS 模块加载 ES6 模块,不能使用require命令,而要使用import()函数。
- // es.mjs
- let foo = { bar: 'my-default' };
- export default foo;
-
- // cjs.js
- const es_namespace = await import('./es.mjs');
- // es_namespace = {
- // get default() {
- // ...
- // }
- // }
- console.log(es_namespace.default);
- // { bar:'my-default' }
- 复制代码
参考链接:
作者:一颗白菜
链接:https://juejin.im/post/6844903598480965646
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。