美文网首页
自己模拟实现exports和module.exports导出功能

自己模拟实现exports和module.exports导出功能

作者: yahzon | 来源:发表于2018-02-24 09:58 被阅读10次

    创建一个foo.js文件,内容如下:
    exports.foo = 'bar';
    创建index.js文件,内容如下:
    // 1. 在Node中,每个文件模块都是一个对象,我们模拟一个

    function Module() {
      this.exports = {};
    }
    

    // 2. Node在定位到具体的文件后,Node会新建一个模块对象

    var module = new Module();
    

    // 3. 如果是.js文件。Node会通过fs模块同步读取文件

    var fs = require('fs');
    var foo_js = fs.readFileSync('./foo.js');
    

    // 4. 读取出文件内容后,将文件进行头尾包装,这里只是简单的模拟

    var packStr = '(function(exports,module){' + foo_js + ' return module.exports; })';
    

    // 注:这样每个模块之间都进行了作用域隔离

    // 5. 包装之后的代码通过一个类似eval(Node中并不是eval)的函数执行返回一个具体的function对象

    var packObj = eval(packStr);
    

    // 6. 执行该函数,将module对象的exports属性以及module对象本身作为参数传递进去
    // 而内部是通过return module.exports; 的方式返回的

    var foo = packObj(module.exports, module);
    

    // 在第6点中,就是为什么通过exports = ‘bar’; 赋值,但是外部却拿不到
    // 这是因为在JavaScript中,引用传递的是引用的副本,而不是引用本身,这叫做共享传递
    // 所以exports = ‘bar’ 改变的是形参的引用()而并没有影响到外部的实参exports对象
    // 而通过exports.foo = ‘bar’; 确实可以得到,这是因为虽然引用传递的是引用副本,但他们指向的是同一个对象
    // 自然而然的,通过module.exports = ‘bar’; 就是成功的

    // 7. 所以在外部我们最终得到了被引用模块中导出的变量、函数或对象

    console.log(foo);
    

    相关文章

      网友评论

          本文标题:自己模拟实现exports和module.exports导出功能

          本文链接:https://www.haomeiwen.com/subject/oifqxftx.html