javascript模块化编程

来源:互联网 发布:js replacefirst 编辑:程序博客网 时间:2024/06/05 14:26

   假定现在有一个test.js文件,它定义了一个test模块。那么,test.js就要这样写:

  // test.js

  define([‘math’],function (math){

    var sum= function (x,y){

      return math.add(x,y);

    };

    return {

      sum: sum;
    };

  });

加载方法如下:

  // main.js

  require(['test'], function (test){

    alert(test.sum(1,1));

  });

  整个过程可以看作如下过程

var test={

     sum:function(x,y){

     return math.add(x,y);  

     }

} ;

(function(test){

alert(test.sum(1,1));

}(test));

当require()函数加载上面这个模块test的时候, 可以看作模块中定义的返回对象将作为一个局域对象test被创建,或者是模块中的返回对象将作为参数传入function而被调用。

总而言之,调用一个模块实际上是调用的模块返回值,并将返回值作为参数传给匿名function(A,B,...),其中的A,B属于形参,不必与模块同名,模块的返回值将会作为实参依次传给形参!

require()加载模块时,相当于对模块的执行,即对模块中匿名函数的执行,如果模块中引用了其他模块,则define变为require对引用的模块进行执行,获得返回参数,再对模块的匿名函数进行执行,模块的匿名函数执行后将返回模块的返回值,并作为参数,传入当前的匿名函数中,即刻执行!

所以,整个过程不只是模块文件的加载的过程,而是模块的执行过程,执行结束后将会有返回值,可能是函数对象,也可能就是一个字面量对象,包含一般属性和对象属性,总之,返回的并非一个简单的值,而是对象,一般包含函数以供调用。

   

  require(['test'], function (test){

  alert(test.sum(1,1));

  });

相当于

var test = require([‘math’],function (math){

    var sum= function (x,y){

      return math.add(x,y);

    };

    return {

      sum: sum;
    };

  });

  function (){

  alert(test.sum(1,1));

  };


require()函数接受两个参数。第一个参数是一个数组,表示所依赖的模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。

require()异步加载module,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。

而模块的加载就是对模块回调函数的调用,理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。

换个角度看:

如果没有require,我们怎么在一个文件中加载其他多个文件,嵌入js代码到当前文件中呢?

<script src="js_path"></script>

那么我们的js文件会怎么写?

那就是一段可以直接执行的js代码,包括变量,函数等的定义,运算等

那如果要在一个js中依赖另一个js文件怎么办?

因为js文件是一段js代码,所以,需要在整个js程序运行时,保持依赖关系的正确,即被依赖的js文件应当先于依赖它的js文件被加载,以此来实现js之间的相互依赖,拼成一个完整的js程序。比如2依赖于1时,保持<script src="1.js"></script><script src="2.js"></script>这样的加载顺序!

那么这样子的问题在哪呢?

第一、依赖关系太复杂时,管理太困难。

第二、文件加载时会停止页面渲染,网页失去响应。

谁来解决这个问题呢?

require应运而生,用define将js文件定义为模块,然后,利用require对模块进行加载,而模块将会返回一个整合的对象嵌入到程序中,而不是一段js代码,模块可以对象化调用其属性!