• es6和commonjs对导入导出的值修改是否影响原模块


    文章目录

    都说es6的导出是引用,commonjs导出是值拷贝,所以我想测试一下:

    commonjs

    commonjs对引用类型导出:对导出的引用修改,会改变模块的值,且引用了该模块的模块都可以获取最新值

    // a.js
    module.exports.x = "default1";
    setTimeout(() => {
      module.exports.x = 6;
    }, 4000);
    setInterval(() => {
      console.log('a',module.exports);
    }, 1000);
    
    // b.js
    let a = require("./a.js");
    setInterval(() => {
      console.log('b',a);
    }, 1000);
    setTimeout(() => {
      a.x = "2";
    }, 2000);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    结果为:

    a { x: 'default1' }
    b { x: 'default1' }
    a { x: '2' }
    b { x: '2' }
    a { x: '2' }
    b { x: '2' }
    a { x: 6 }
    b { x: 6 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    commonjs对基本数据类型导出:外部修改无效(会脱离指向),内部的修改,无法反映到外部!

    // a.js
    module.exports = "default1";
    setTimeout(() => {
      module.exports = 6;
    }, 4000);
    setInterval(() => {
      console.log('a',module.exports);
    }, 1000);
    
    // b.js
    let a = require("./a.js");
    setInterval(() => {
      console.log('b',a);
    }, 1000);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    结果为:

    a default1
    b default1
    a default1
    b default1
    a default1
    b default1
    a 6
    b default1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    es6

    对于es6导出的引用类型数据,任何一个地方的更改都会影响别的地方的数据!

    // a.js
    let x = {name:"default1"};
    export let y = {name:"default2"};
    export default x;
    setTimeout(() => {
      x.name = "4";
      y.name = "4";
    }, 4000);
    setInterval(() => console.log("a", x, y), 1000);
    
    // b.js
    import x from "./a.js";
    import { y } from "./a.js";
    setInterval(() => console.log("b", x, y), 1000);
    setTimeout(() => {
      x.name = "2";
      y.name = "2";
    }, 2000);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    结果:

    a {name: 'default1'} {name: 'default2'}
    b {name: 'default1'} {name: 'default2'}
    a {name: 'default1'} {name: 'default2'}
    b {name: 'default1'} {name: 'default2'}
    a {name: '2'} {name: '2'}
    b {name: '2'} {name: '2'}
    a {name: '4'} {name: '4'}
    b {name: '4'} {name: '4'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    换成基本类型数据,测试结果:无法在外部改变引入模块的值,因为是只读属性引入的,但是内部改变后可以被外部非默认导出获取到最新值!

    // a.js
    let x = 'default1';
    export let y = 'default1';
    export default x;
    setTimeout(() => {
      x = "4";
      y = "4";
    }, 4000);
    setInterval(() => console.log("a", x, y), 1000);
    
    // b.js
    import x from "./a.js";
    import { y } from "./a.js";
    setInterval(() => console.log("b", x, y), 1000);
    setTimeout(() => {
      x = "2"; // 报错!提示常量无法赋值
      y = "2"; // 报错!提示常量无法赋值
    }, 2000);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    结果:

    a default1 default1
    b default1 default1
    a default1 default1
    b default1 default1
    报错了。。。
    a default1 default1
    b default1 default1
    a 4 4
    b default1 4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    总结


    • 在模块导出基本类型数据时,require方式无法获取内部最新数据而且修改变量值会脱钩,import方式外部无法修改模块的数据(只读),但是非默认导出属性可以获取内部最新值。
    • 在模块导出引用类型数据时,外部和内部的修改都可以被观测到!

  • 相关阅读:
    【React】React组件生命周期以及触发顺序(部分与vue做比较)
    Javaweb:HTTP协议与Web服务端开发环境(一)
    ble理论(14) ble扫描详解
    Ubuntu工控机CAN卡驱动安装(手动安装)
    OpenCV之基本绘图
    C Primer Plus(6) 中文版 第11章 字符串和字符串函数 11.1 表示字符串和字符串I/O
    大数据毕业设计选题推荐-生产大数据平台-Hadoop-Spark-Hive
    c语言自动类型转换
    登录认证方式汇总,例如ThreadLocal+拦截器+Redis、JWT
    SpringCloud Sleuth+Zipkin
  • 原文地址:https://blog.csdn.net/xiapi3/article/details/126036736