zoukankan      html  css  js  c++  java
  • js模块化

    后端的commonjs规范

    一. nodejs中, 只能有一个入口文件, 即启动文件. 在开发时候, 需要尽可能细致的分多个文件, 就产生了模块化规范的要求.

    二. 模块化有两个核心要素: 隐藏和暴露;

     1. 有导入和导出的文件叫模块.

     2. 模块内的所有代码都是隐藏的, 不会污染全局.

     3. 导出: 将模块化的内容暴露的过程就是导出.

     4. 导入: 获取导出内容的过程

    三. commonjs的导入导出

      1.导出:

     文件内的代码相当于放到一个立即执行函数中

    如:

    //a.js模块
    const
    c = 3; module.exports = { a: 1, b: 2, c: c }
    模块中的代码, 放到上面的立即执行函数内, 导出的结果{a:1,b:2,c:3};

     注意: 导出的最终结果是module.exports, 而不是exports. 

              因此, exprots改变指针指向, 并不会造成导出内容的变化.

      2.require导入

           导入的结果是导出的结果. 

           模块缓存: 第一次导入会加载文件, 然后执行文件, 将执行后的内容存到一块缓存区域里

                         下次导入文件前, 先检查模块缓存中是否存在,

                                                       如果存在, 会直接从缓存中取,

                                                        如果不存在, 才去加载文件执行文件获取导出结果.

    commonjs的执行过程, 或者原理就是:

             1.用nodejs读取文件,

             2. 将文件作为立即执行函数的执行内容

             3. 返回module.exports的值.


    前端过渡阶段的amd和cmd

    一: 为什么在浏览器不能用commonjs规范.

         1.由于commonjs中require函数的执行是同步的;

          2. 浏览器到服务器获取是通过网络请求, 与commonjs中用nodejs直接读取文件相比,  网络请求会慢的多. 失败风险也大的多. 会导致执行缓慢甚至堵塞.

    二. 解决思路, 用异步回调代替commonjs的require

    三. AMD规范: 

             define(["模块1","模块二"...], function(arg1, arg2){  //arg1和arg2分别对应模块1和模块2的返回值, 

                //等加载完所有模块, 该回调函数会执行

               } )

    四. cmd规范:

            define(function(require, exports, module){

            //用require导入,

            })

         可以看出, cmd为了方便开发人员, 将后端nodejs的api习惯带入了前端模块化.


    es6模块化

    commonjs的导入;

    1.依赖延迟声明, 优点是某些条件下能够减少模块加载量,

    比如: if(xx){require("./a.js")}else{require("./b")}这样就会少加载一个文件,而不是a  b两个文件都加载

          2.导入路径./或../开头 与直接写文件名含义不一样;

    es6的导入导出特点:

          1.依赖预声明:,优点是依赖关系明确, 上来就能看到引入的所有模块, java, c语言都用这种导入模式.

           2.规范的路径表示方法: 必须以./或者 ../开头, 不能直接写文件名.

           3.灵活多样导出方式和导入方式.

    导入导出分基本导入导出和默认导入导出;

                基本导入导出和默认导入导出二者可以同时存在

                基本导入导出可以有多个, 默认导入导出只能有一个

                基本导入导出因为有多个, 所以必须具名. 即后面必须用表达式, 默认导出只有一个, 所以不需要.

    基本导出语法: 

           1.export 声明表达式:  

                  export var  a=1;

           2. export {变量}

                   var a = 1; export {a}; //相当于 导出的名字是a, 值是1. 

                   注意: export a是错误的.

    基本导入语法: 

           1. 导入其中某个或某几个模块的值,

                   import {a  [as  xx]} from "a.js";   

            2.导入所有值. 

                  import * as obj from "a.js"

    注意. 导入的值禁止更改. 是一个常量值.   

    默认导出: 

             export default xx;   //xx可以是变量名, 字符串, 对象等

    默认导入

             import a from "/a.js"   表示将a.js里的默认导出赋值给常量a

             import * as data from "a.js";  //data里有{default: xx, 基本导出} 

    注意: 导出的数据是常量, 最好用const声明. 

    es6导出和commonjs导出的结果有什么不一样:es6的导出结果不能更改,而commonjs导出结果可以更改的

    如果用es6导入后更改,会报错

    1、CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。

    2、所谓值的拷贝,原始类型的值被缓存,不随模块内部的改变而改变。

    3、ES6 模块是动态引用,不缓存值,模块内外是绑定的,而且是只读引用,不能修改值。ES6 的 js 引擎对脚本静态分析的时候,遇到加载命令模块 import ,就会生成一个只读引用,当真正用到模块里边的值的时候,就会去模块内部去取。

    4、CommonJS 模块是运行时加载,ES6 模块是编译时加载输出接口。

    5、运行时加载:CommonJS 模块就是对象;是先加载整个模块,生成一个对象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”。
    6、编译时加载: ES6模块不是对象,而是通过 export 命令「显式指定输出的代码」。import 时采用静态命令的形式,即在import指定「加载某个输出值」,而「不是加载整个模块」,这种加载称为“编译时加载”。

    7、import的接口是read-only(只读状态),不能修改其变量值。 即不能修改其变量的指针指向,但可以改变变量内部指针指向,可以对commonJS对重新赋值(改变指针指向),但是对ES6 Module赋值会编译报错。

  • 相关阅读:
    C#中文件操作【File】和【Directory】
    MySql的不同之处
    FileStream读写文件【StreamWriter 和 StreamReader】
    将对象序列化为XML文档
    SQL自增长的数据插入
    POJ3356 AGTC (最短编辑距离问题)
    POJ3070Fibonacci(矩阵快速幂求Fibonacci数列)
    HDOJ1058 Humble Numbers
    第三届软件大赛预赛A组试题及答案
    HDOJ4526 威威猫系列故事——拼车记
  • 原文地址:https://www.cnblogs.com/dangdanghepingping/p/14479898.html
Copyright © 2011-2022 走看看