common JS与 ES Modules区别

common JS 和 ES Modules区别:

引入方式:
    1. common JS时动态引入,可以在代码任何一个地方引入。
	2. ES Modules 静态导入(在编译阶段导入),import不能写在块级作用域饿判断条件内。 并且会提升到模块头部。
使用方法:

common JS通过module.exports 导出模块对象, require()导入一个模块对象

ES Modules 通过export 导出指定数据, import 引入具体数据。

模块导入导出:

1.1. 当module.exports的值是数字,字符串等原始类型时,赋值是值的拷贝,这样才会产生导出值的改变不会影响到导入值改变的现象。

// # 导出模块 a.js
    let title = 'hello hi'
    setTimeout(() => {
        title = 'hello hehe'
    }, 2000)
    module.exports = title

    // # 导入模块 b.js
    const title = require('./a.js')
    setTimeout(() => {
    console.log(title)
    }, 4000)
    console.log(title)

    // # 输出结果
    hello hi
    hello hi

// 可以看出模块内部title的改变,并没有影响到导入模块的值

1.2. 如果module.exports导出的是一个对象,导出值的改变是否会影响到导入的值,这个跟导入时赋值的方式是有直接关系的。

    const obj = {
        title: 'hello hi'
    }
    setTimeout(() => {
        obj.title = 'hello hehe'
    }, 2000)
    module.exports = obj

    // # 导入模块 b.js
    const obj = require('./a.js')
    setTimeout(() => {
    console.log(obj.title)
    }, 4000)
    console.log(obj.title)

    // # 输出结果
    hello hi
    hello hehe

    // 可以看出输出的值变了,说明模块内部值的变化导致了导入对象值的变化
    // 这里的赋值实际上就是引用赋值,module.exports导出的对象被赋值到导入的模块,两者指向同一块内存空间

    // # 导出模块 a.js
    const obj = {
        title: 'hello hi'
    }
    setTimeout(() => {
        obj.title = 'hello hehe'
    }, 2000)
    module.exports = obj

    // # 导入模块 b.js
    const { title } = require('./a.js')
    setTimeout(() => {
    console.log(title)
    }, 4000)
    console.log(title)

    // # 输出结果
    hello hi
    hello hi

    // 可以看出输出的值没有发生变化,说明模块内部值的变化没有导致导入值的变化
    // 这里的赋值实际上就是值的拷贝,通过对象解构的方式直接给变量title赋值,所以模块内部对象值的变化不会影响到导入变量值的变化

  1. esModule模块输出的是一个值的引用, 使用的是动态绑定,esModule导入导出的值都指向同一个内存地址,所以导入值会跟着导出值发生变化。

      2.1 JS引擎对脚本进行静态分析的时候,如果遇到模块加载命令import,就会生成一个只读引用,等到脚本真正执行的候,再通过这个只读引用,到被加载的模块中去取值。
      2.2 esModule导入的基本类型值在当前模块不能直接进行修改(代码会报错,但是可以通过调用模块内的方法进行修改),也就是说基本类型的值在被导入的模块中是只读状态,对于导入引用类型的值,可以直接进行修改设置,但是不会对模块内的值产生任何影响
    
// # 导出模块 a.js
export let title = 'hello hi'
const obj = {
    name: 'tom'
}
export default obj
setTimeout(() => {
    title = 'hello world'
    obj.name = 'tony'
}, 2000)

// # 导入模块 b.js
import obj, { title } from './a.js'
console.log(title)
console.log(obj.name)
setTimeout(() => {
    console.log(title)
    console.log(obj.name)
}, 4000)

// # 输入结果
hello hi
tom
hello world
tony

// 可以看出输出的值发生了变化,这是因为导入和导出的值都指向同一内存地址,值变化,取值也就发生变化
加载方式:

common JS 运行时加载(同步);ES Modules 静态加载(异步)。

common JS输出的是一个对象,该对象需要在模块脚本运行完成后才能生成,二ES Module 在编译时能生成。

你可能感兴趣的:(前端,javascript,elasticsearch,前端)