为何给这两个单独拿出来放前面说,由于过重要了! 先用人话解释一下: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
这些进制之间怎么转换呢? 各类进制转化为十进制用Math.parseInt();十进制转为其余进制能够利用toString()方法。数组
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')
})
复制代码
怎么声明bufferapp
另外说明一点的是:buffer是内存地址的引用,能够修改的函数
buffer的几个常见方法:ui
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