express简谈
express对于node.js是一种什么样的存在?就像mvc对于.net,就像spring.mvc对于java,是一个装机量特别多的开源,web框架。github地址
推荐使用visual studio code 进行代码下载,查看,微软开发的专门进行web开发的轻量级工具。
express结构
源代码visual studio code下载代码,主要源码有两个,一个lib文件夹和index.js。index.js算是express的入口文件。
express使用
var express = require('express');
var app = express();
第一行引用express模块,引用的文件在package.json配置。
"main": "xxxx.js",
express中没有main这个属性,因为express默认使用根目录下的index.js
//默认会查找express根目录下的index.js
var express = require('express');
index.js
module.exports = require('./lib/express');
index.js对外导出函数createApplication
./lib/express
'use strict';
/**
* 依赖的模块
*/
var EventEmitter = require('events').EventEmitter;
var mixin = require('merge-descriptors');
var proto = require('./application');
var Route = require('./router/route');
var Router = require('./router');
var req = require('./request');
var res = require('./response');
/**
* express对外导出了一个函数,createApplication,所以在创建app的时候需要express();
*/
exports = module.exports = createApplication;
function createApplication() {
//创建一个app的函数
var app = function(req, res, next) {
//app调用了一个handle函数,处理请求
app.handle(req, res, next);
};
//mixin在这里的作用,对象属性复制的手段,另类的继承
mixin(app, EventEmitter.prototype, false);
mixin(app, proto, false);
//继承的手段
/*创建request对象,request的原型为req,也就是request继承req;并在request对象上添加了一个app属性;
*/
app.request = Object.create(req, {
app: { configurable: true, enumerable: true, writable: true, value: app }
})
// 创建response对象,同上
app.response = Object.create(res, {
app: { configurable: true, enumerable: true, writable: true, value: app }
})
//调用初始化
app.init();
//返回
return app;
}
propertiesObject
merge-descriptors
merge-descriptors 源码复制源对象的自有属性到目标对象上面,默认重写目标对象上的同名属性
'use strict'
/**
* Module exports.
* @public
*/
module.exports = merge
/**
* Module variables.
* @private
*/
var hasOwnProperty = Object.prototype.hasOwnProperty
function merge(dest, src, redefine) {
//判断,抛出异常
if (!dest) {
throw new TypeError('argument dest is required')
}
//判断,抛出异常
if (!src) {
throw new TypeError('argument src is required')
}
//默认重新定义未True
if (redefine === undefined) {
// Default to true
redefine = true
}
//获取所有src对象中的自身属性的属性名称集合并循环处理(不包括原型链上的)
Object.getOwnPropertyNames(src).forEach(function forEachOwnPropertyName(name) {
//判断如果redefine=false并且目标对象中含有名称为name的属性,则跳过
if (!redefine && hasOwnProperty.call(dest, name)) {
// Skip desriptor
return
}
// 获取src对象中name属性的propertiesObject
var descriptor = Object.getOwnPropertyDescriptor(src, name)
//在目标对象中创建属性名称=name,propertiesObject=descriptor
Object.defineProperty(dest, name, descriptor)
})
//结束
return dest
}
结语
createApplication函数中采用了两种'继承'方式,来完成对象的创建,扩展,所以在app对象上面那些我们不知道的函数,属性其实都是其他模块依赖过来的对象中的函数,属性。
网友评论