帶你一塊兒擼一遍 nodejs 經常使用核心模塊(一)

module.exports,exports,require

爲何給這兩個單獨拿出來放前面說,由於過重要了! 先用人話解釋一下:module就是require的時候建立的一個對象,而且返回了 module.exports,exports = module.exports;(緊緊記住) 咱們來看本身實現一個:node

let path = require('path');
let fs = require('fs');
let vm = require('vm');
function Module(filename) {  //構造函數
    this.loaded = false;
    this.filename = filename;
    this.exports = {}          //模塊對應的導出結果
}
Module._extensions = ['.js', '.json']  //靜態屬性

Module._resolveFilename = function(p) {  //靜態方法
    p = path.join(__dirname, p);
    if (!/\.\w+$/.test(p)) {
        for (let i = 0; i<Module._extensions.length; i++) {
            let filepath = p + Module._extensions[i];

            try{
                fs.accessSync(filepath);
                return filepath;
            } catch(e) {
                if(i >= Module._extensions.length) {
                    throw new Error('module not Found')
                }
            }

        }
    } else {
        return p
    }
}
Module._cache = {};    //靜態屬性 外部沒法更改 沒法調用

Module._extensions['.json'] = function (module) {
    let content = fs.readFileSync(module.filename,'utf8');
    module.exports = JSON.parse(content)
}
Module.wrapper = ['(function (exports,require,module){','\r\n})'];  
//經過這個包裹 使得exports = module.exports;
Module.wrap = function (content) {
  return Module.wrapper[0] + content + Module.wrapper[1];
}
Module._extensions['.js'] = function (module) {
  let content = fs.readFileSync(module.filename, 'utf8');
  let script = Module.wrap(content);
  let fn = vm.runInThisContext(script);
//   module.exports = exports = {}
  // exports.a = 'hello world'
  fn.call(module.exports, module.exports, req, module);
}
Module.prototype.load = function () {
  // 加載模塊自己 js按照js加載 json按照json加載
  let extname = path.extname(this.filename);
  Module._extensions[extname](this);
}



Module.prototype.load = function () {
    let extname = path.extname(this.filename);
    Module._extensions[extname](this)       //模塊的執行
}

//重點require就是給module.exports導出的代碼包了一層,而後module.load()執行並取得返回值
function req(path) {                    
    let filename = Module._resolveFilename(path);
    if (Module._cache[filename]) {
        return Module._cache[filename].exports;
    }
    let module = new Module(filename)
    module.load();  //讓這個模塊進行加載 根據不一樣的後綴加載不一樣的內容
    Module._cache[fileName] = module;
    return module.exports;
}

複製代碼

宏任務&微任務

進制

數字按照進制可分爲二進制,八進制,十進制和十六進制,在計算機內部呢都是使用的二進制,node中各類進制的表示:json

  • ob表示二進制 ,
  • 0o或者0表示八進制,
  • 0x表示16進制(buffer都是用16進製表示,buffer是啥?後面會說道到)

這些進制之間怎麼轉換呢? 各類進制轉化爲十進制用Math.parseInt();十進制轉爲其餘進制能夠利用toString()方法。數組

util模塊

  1. util.promisify(fn); //十分經常使用
  2. util.inherits(Child, Parent);
  3. util.isArray([]) util.isString();

發佈訂閱

let EventEmitter = require('./events');
let util = require('util');
function My() {}
util.inherits(My,EventEmitter);
let e = new My();
// 訂閱
e.on('水開了',function (who) { // {水開了:[fn,fn]}
  console.log('吃泡麪' + who)
});
e.on('水開了',function (who) {
  console.log('洗臉' + who);
});
// 發佈
e.emit('水開了','我') 
複製代碼

這個地方有一個主意的地方就是 e.on('newListener', cb) 2.bash

let EventEmitter = require('events');
let util = require('util');
function My() {}
util.inherits(My,EventEmitter);
let e = new My();
e.on('newListener',function (type) {
  if(type === 'ok'){
    process.nextTick(()=>{    //這個要注意 必須事件已經被添加進去後才能夠觸發
      e.emit('ok');
    });
  }
})
e.on('水開了',function (who) {
  console.log('吃泡麪' + who)
});
e.on('水開了',function (who) {
  console.log('洗臉' + who);
});
e.on('ok',function () {
  console.log('ok')
})
複製代碼
  1. e.once(event, cb)
  2. e.removeListener(event, cb)

Buffer

怎麼聲明bufferapp

  1. 經過長度 let buffer = Buffer.alloc(length);
  2. 經過字符串聲明 let buffer = Buffer.from('字符串');
  3. 經過數組聲明 let buffer = Buffer.from([0xe7, 0x8f,0xa0])

另外說明一點的是:buffer是內存地址的引用,能夠修改的函數


buffer的幾個常見方法:ui

  • buffer.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
  • Buffer.concat(list[, totalLength]) //和數組相似
const buf1 = Buffer.alloc(10);
const buf2 = Buffer.alloc(14);
const buf3 = Buffer.alloc(18);
const totalLength = buf1.length + buf2.length + buf3.length;

// 輸出: 42
console.log(totalLength);

const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);

// 輸出: <Buffer 00 00 00 00 ...>
console.log(bufA);

// 輸出: 42
console.log(bufA.length);
複製代碼

有時咱們須要給一段字符串進行切割,就像字符串的split方法同樣,可是buffer並無提供一個這樣的方法,咱們本身實現一個吧,代碼以下:this

// indexOf 取索引
let buffer = Buffer.from('xlei愛折騰愛js');
// console.log(buffer.indexOf('*',7));
Buffer.prototype.split = function (sep) {
  let offset = 0;
  let len = Buffer.from(sep).length;
  let arr = [];
  let start = 0;
  while (-1 != (offset = (this.indexOf(sep, start)))) {
    arr.push(this.slice(start, offset));
    start = offset + len;
  };
  arr.push(this.slice(start));
  return arr;
}
// spilt()方法 分割buffer
// [buffer1,buffer2,buffer3]
console.log(buffer.split('愛'));
複製代碼

以上是一部分的核心模塊常見用法以及部分深入解析,不足之處歡迎各位提出寶貴的意見或建議,也但願能幫助到你從中得到一些知識!這是一個系列的文章 還有核心模塊(二)核心模塊(三)等等部分,謝謝你們的關注!spa

相關文章
相關標籤/搜索