nodejs之模块化编程
在网站开发中,难免会用到很多特效,这时会用到很多JavaScript代码,开发的越来越复杂时,难免会出现问题,例如命名冲突、繁琐的文件依赖等等;为了解决这类问题,模块化编程应运而生。
1、模块化的概念
就如同我们的电脑主板一般,有着很多很多的模块:cpu、显卡、各个处理器、寄存器等等等等,这些模块都是独立的个体,又能同时为一台主机协同工作,而这些看似独立的个体就是所谓的“模块”。
模块化编程有一下特点:生产效率高、维护成本低、这是从生产角度来看,从程序开发角度,它对应以下特点:开发效率高、维护成本低
2、什么是命名冲突?
命名冲突就是,差不多这样:
var foo = "bar";
var foo = "ber';
可以从上面的代码看出来,第二个把第一个给覆盖了。
3.何为文件依赖?
例如你需要从外面用到代码:a.js、aa.js; aa.js依赖于a.js
而你调用时:
..忽略部分代码...
<script>aa.js</script>
<script>a.js</script>
..忽略部分代码...
调换了两个文件的顺序,这就会导致运行错误;
4.全局函数
以写一个计算器为例子:
Cal.html
<!DOCTYPE html>
<html>
<head>
<title>Calclator</title>
<meta charset="utf-8">
</head>
<body>
<div id="WO">
<h2>计算器</h2>
<input type="text" id="x">
<select id="opt">
<option value="0">+</option>
<option value="1">-</option>
<option value="2">*</option>
<option value="3">/</option>
<option value="4">%</option>
<input type="text" id="y">
<button id="cal">=</button>
<input type="text" id="result">
</select>
</div>
<div id="AI">I LOVE YOU!</div>
<script type="text/javascript" src="Cal.js"></script>
</body>
</html>
cal.js代码:
function add(x,y){
return parseInt(x)+parseInt(y);
}
function subtract(x,y){
return parseInt(x)-parseInt(y);
}
function multiply(x,y){
return parseInt(x)*parseInt(y);
}
function divide(x,y){
return parseInt(x)/parseInt(y);
}
//下面开始获取DOM元素
var oX = document.getElementById('x');
var oOpt = document.getElementById('opt');
var oY = document.getElementById('y');
var oCal = document.getElementById('cal');
var oResult = document.getElementById('result');
//点击等于号时就会出现结果的监听
oCal.addEventListener('click',function(){
var x = oX.value.trim();
var y = oY.value.trim();
var opt = oOpt.value;
var result = 0;
switch(opt){
case '0':
result = add(x,y);
break;
case '1':
result =subtract(x,y);
break;
case '2':
result = multiply(x,y);
break;
case '3':
result = divide(x,y);
break;
case '4':
result = mod(x,y);
break;
}
oResult.value = result; //赋值给result
})
这个nodejs代码分别定义了加、减、乘、除、取余等函数功能,并且是可以用的:
![](https://img.haomeiwen.com/i16095021/f96f44eec42f994b.png)
可以看出来是完整的功能实现;
虽然使用全局函数这个方式是我们常见的方式,但是不可取,因为所有的函数变量都是暴露在全局的,不能保证不发生冲突,而且成员之间看不出来直接关系;
这时可以用命名空间:
定义语法:
var calculator = {}
往命名空间里加函数语法
calculator.add = function (x,y){return parseInt(x)+parseInt(y)};
虽然解决了函数命名空间的问题了,但是如果再定义一个命名空间为calculator,还是会再次的报错。内部人员可以随便改写,不安全。
子命名空间:
定义在命名空间下,例如:
calculator.subcal = {}
calculator.subcal.foo = 'bar';
虽然可以用这种方式,但是,命名空间的名字会越来越长,不容易记忆。代码可读性差。
5、函数的作用域(闭包)
以上介绍道全局函数和命名空间都不是很好的解决命名冲突问题.而且私有属性没有得到很好的保护。
这时就可以通过封装函数的私有空间,让属性和方法的到私有化,这就是所谓的闭包。
语法:
var calculator = (function(){
function add(x,y){
return parseInt(x)+parseInt(y)
}
return{
add:add,
}
})();
很显然的看到了封装了一个函数。这时如果不加返回值,所定义的函数是无法被访问到的。添加返回之后,可以通过“匿名函数.函数名()”的方式调用。
6维护和拓展
使用以上方法固然是好,但是,如果中途我又想加入一个别的函数功能的话,应该怎么办?这时候都会想到就是在代码中加,例如要对以上函数进行添加一个做减法的函数,则应该:
var calculator = (function(){
function add(x,y){
return parseInt(x)+parseInt(y)
}
function subtract(x,y){
return parseInt(x)-parseInt(y)
}
return{
add:add,
subtract:subtract,
}
})();
虽然说这样也是可以,但是如果要添加的函数是来自第三方的库提供的呢,那就会更麻烦了。于是可以通过传递参数的方式来添加函数:
语法:
var calculator = (function(cal){
function add(x,y){
return parseInt(x)+parseInt(y)
}
cal.add = add;
return cal;
})(calculator || {})
//这时如果要对函数模块进行扩充时,可以使用相同的方式
var calculator = (function(cal){
function subtract(x,y){
return parseInt(x)-parseInt(y)
}
cal.subtract = subtract;
return cal;
})(calculator || {});
这时会发现,定义的第二个calculator会不会把第一个calculator给覆盖掉?
答案当然是不会,因为代码“calculator || {} ”的意思就是:当拓展模块时,判断calculator是否存在,如果存在,则不需要重新创建,如果不存在就重新创建。
ok,这就是模块化编程了的思想了。(差不多思想)
参看教材:nodejs 核心技术卷
网址:http://www.qmwan.club/index.php/2020/02/06/63/
网址:http://leanote.com/blog/post/5dcbe0c0ab64414703000427
作者:Kenny技术仔 个人联系邮箱:zhangdlmj@163.com
欢迎交流 QQ:908481391
网友评论