zoukankan      html  css  js  c++  java
  • [转]模块化——Common规范及Node模块实现(二)

    模块的循环加载

    如果发生模块的循环加载,即A加载B,B又加载A,则B将加载A的不完整版本。

    // a.js
    exports.x = 'a1';
    console.log('a.js ', require('./b.js').x);
    exports.x = 'a2';
    
    // b.js
    exports.x = 'b1';
    console.log('b.js ', require('./a.js').x);
    exports.x = 'b2';
    
    // main.js
    console.log('main.js ', require('./a.js').x);
    console.log('main.js ', require('./b.js').x);

    上面代码是三个JavaScript文件。其中,a.js加载了b.js,而b.js又加载a.js。这时,Node返回a.js的不完整版本,所以执行结果如下。

    修改main.js,再次加载a.js和b.js。

    // main.js
    console.log('main.js ', require('./a.js').x);
    console.log('main.js ', require('./b.js').x);
    console.log('main.js ', require('./a.js').x);
    console.log('main.js ', require('./b.js').x);

    执行上面代码,结果如下。

    
    

    上面代码中,第二次加载a.js和b.js时,会直接从缓存读取exports属性,所以a.js和b.js内部的console.log语句都不会执行了。

    require.main

    require方法有一个main属性,可以用来判断模块是直接执行还是被调用执行

    直接执行的时候(node module.js),require.main属性指向模块本身。

    
    

    调用执行的时候(通过require加载该脚本执行),上面的表达式返回false。

    模块的加载机制

    CommonJS模块的加载机制是输入的是被输出的值的拷贝。也就是说,一旦输出一个值模块内部的变化就影响不到这个值。请看下面这个例子。

    下面是一个模块文件lib.js

    // lib.js
    var counter = 3;
    function incCounter() {
      counter++;
    }
    module.exports = {
      counter: counter,
      incCounter: incCounter,
    };

    上面代码输出内部变量counter和改写这个变量的内部方法incCounter

    然后,加载上面的模块。

    // main.js
    var counter = require('./lib').counter;
    var incCounter = require('./lib').incCounter;
    
    console.log(counter);  // 3
    incCounter();
    console.log(counter); // 3

    上面代码说明,counter输出以后,lib.js模块内部的变化就影响不到counter了。

    require的内部处理流程

    require命令是CommonJS规范之中,用来加载其他模块的命令。它其实不是一个全局命令,而是指向当前模块的 module.require 命令,而后者调用Node的内部命令Module._load

    上面的第4步,采用module.compile()执行指定模块的脚本,逻辑如下。

    上面的第1步和第2步,require函数及其辅助方法主要如下。

    一旦require函数准备完毕,整个所要加载的脚本内容,就被放到一个新的函数之中,这样可以避免污染全局环境。该函数的参数包括requiremoduleexports,以及其他一些参数。

    (function (exports, require, module, __filename, __dirname) {
      // YOUR CODE INJECTED HERE!
    });

    Module._compile方法是同步执行的,所以Module._load要等它执行完成,才会向用户返回module.exports的值。

  • 相关阅读:
    STL_算法_查找算法(lower_bound、upper_bound、equal_range)
    Kafka深度解析
    hdoj 1027 Ignatius and the Princess II 【逆康托展开】
    代码二次封装-xUtils(android)
    C++11新特性应用--介绍几个新增的便利算法(用于排序的几个算法)
    谨防串行的状态报告会
    hadoop中NameNode、DataNode和Client三者之间协作关系及通信方式介绍
    Kindeditor JS 取值问题以及上传图片后回调等
    MySQL 8.0.11 报错[ERROR] [MY-011087] Different lower_case_table_names settings for server ('1')
    爱的链条
  • 原文地址:https://www.cnblogs.com/xuzhudong/p/8947837.html
Copyright © 2011-2022 走看看