• 浅析import与require的基本用法、引入方式区别以及在模块加载时间、模块本质、性能、严格模式、值与引用的5个方面区别、export导出模块接口


      在 es6 之前 JS 一直没有自己的模块语法,为了解决这种尴尬就有了require.js等AMD或CMD方式的出现。在 es6 发布之后 JS 又引入了 import 的概念使得不清楚两者之间的区别的同学在实际使用过程中造成了自己的误解,在查阅了相关资料之后在此记录下自己的小小见解。

    一、require 与 import 基本用法及引入方式区别

    1、require的基本语法

      核心概念:在导出的文件中定义 module.export,导出的对象的类型不予限定(可以是任何类型,字符串,变量,对象,方法),在引入的文件中调用 require() 方法引入对象即可。

    //a.js中
    module.export = {
        a: function(){
         console.log(666)
      }
    }
    
    //b.js中
    var obj = require('../a.js')
    obj.a()  //666

      本质上是将要导出的对象赋值给module这个的对象的export属性,在其他文件中通过require这个方法访问该属性

      require 的使用非常简单,它相当于module.exports的传送门,module.exports后面的内容是什么,require的结果就是什么,对象、数字、字符串、函数……再把require的结果赋值给某个变量,相当于把requiremodule.exports进行平行空间的位置重叠

    require('./a')(); // a模块是一个函数,立即执行a模块函数
    var data = require('./a').data; // a模块导出的是一个对象
    var a = require('./a')[0]; // a模块导出的是一个数组

    2、import的基本语法

      核心概念:导出的对象必须与模块中的值一一对应,换一种说法就是导出的对象与整个模块进行解构赋值。抓住重点,解构赋值!

    //a.js中
    // 最常使用的方法,加入default关键字代表在import时可以使用任意变量名且不需要花括号{}
    export default {
         a: function(){
             console.log(666)
       }
    }
    export function(){  //导出函数
    }
    export {newA as a ,b,c}  //  解构赋值语法(as关键字在这里表示将newA作为a的数据接口暴露给外部,外部不能直接访问a)
     
    //b.js中
    import  a  from  '...'  //import常用语法(需要export中带有default关键字)可以任意指定import的名称
    
    import {...} from '...'  // 基本方式,导入的对象需要与export对象进行解构赋值。
     
    import a as biu from '...'  //使用as关键字,表示将a代表biu引入(当变量名称有冲突时可以使用这种方式解决冲突)
    
    import {a as biubiubiu,b,c}  //as关键字的其他使用方法

    二、require 与 import 主要区别

    1、区别1:模块加载的时间

      require:运行时加载  ——  require 是赋值过程,且是运行时才执行

      import:编译时加载(效率更高)—— import 是解构过程,且是编译时执行

      由于是编译时加载,所以 import 命令会提升到整个模块的头部,下面代码不会报错,正常执行

    test();
    import { test} from '/test';

    2、区别2:对性能的影响

      require的性能相对于import稍低:因为 require 是在运行时才引入模块,并且还赋值给某个变量;

      而 import 只需要依据 import 中的接口在编译时引入指定模块,所以性能稍高。

    3、区别3:模块的本质

      require:模块就是对象,输入时必须查找对象属性

      import:ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,再通过 import 命令输入(这也导致了没法引用 ES6 模块本身,因为它不是对象)。由于 ES6 模块是编译时加载,使得静态分析成为可能。有了它,就能进一步拓宽 JavaScript 的语法,比如引入宏(macro)和类型检验(type system)这些只能靠静态分析实现的功能。

    // CommonJS模块
    let { exists, readFile } = require('fs');
    // 等同于
    let fs = require('fs');
    let exists = fs.exists;
    let readfile = fs.readfile;

      上面CommonJs模块中,实质上整体加载了fs对象(fs模块),然后再从fs对象上读取方法

    // ES6模块
    import { exists, readFile } from 'fs';

      上面ES6模块,实质上从fs模块加载2个对应的方法,其他方法不加载

    4、区别4:严格模式

      CommonJs模块和ES6模块的区别:

    (1)CommonJs模块默认采用非严格模式

    (2)ES6 的模块自动采用严格模式,不管你有没有在模块头部加上 “use strict”;

    (3)CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用,举例如下

    // m1.js
    export var foo = 'bar';
    setTimeout(() => foo = 'baz', 500);
    // m2.js
    import {foo} from './m1.js';
    console.log(foo); //bar
    setTimeout(() => console.log(foo), 500); //baz

      在 commom.js 中 module.export 之后导出的值就不能再变化,但是在 es6 的 export 中是可以的。

    var a = 6
    export default {a}
    a = 7  //在es6中的export可以
    
    var a = 6
    module.export = a
    a = 7   //在common.js中,这样是错误的

    三、export导出模块接口

    1、在要导出的接口前面,加入export指令。

    // a.js
    export default function() {}
    export function a () {}
     
    var b = 'xxx';
    export {b}; // 这是ES6的写法,实际上就是{b:b}
    setTimeout(() => b = 'ooo', 1000);
    export var c = 100;

    2、错误演示

    // 错误演示
    export 1; // 绝对不可以
    var a = 100;
    export a;

      export 在导出接口的时候,必须与模块内部的变量具有一一对应的关系。直接导出1没有任何意义,也不可能在import的时候有一个变量与之对应。 export a 虽然看上去成立,但是 a 的值是一个数字,根本无法完成解构,因此必须写成 export {a} 的形式。即使a被赋值为一个function,也是不允许的。而且,大部分风格都建议,模块中最好在末尾用一个export导出所有的接口,例如:

    export {fun as default,a,b,c};

    3、S6中export及export default的区别

      相信很多人都使用过 export、export default、import,然而它们到底有什么区别呢?

      在JavaScript ES6中,export与export default均可用于导出常量、函数、文件、模块等,你可以在其它文件或模块中通过 import+(常量 | 函数 | 文件 | 模块)名 的方式,将其导入,以便能够对其进行使用,但在一个文件或模块中,export、import 可以有多个,export default仅有一个。

  • 相关阅读:
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark RDD(Resilient Distributed Datasets)论文
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    【机器学习实战】第10章 K-Means(K-均值)聚类算法
    [译]flexbox全揭秘
  • 原文地址:https://www.cnblogs.com/goloving/p/15110728.html
Copyright © 2020-2023  润新知