收藏本站 收藏本站
積木網首頁 - 軟件測試 - 常用手冊 - 站長工具 - 技術社區
首頁 > JavaScript > JavaScript技巧 > 正文

首頁 - PHP - 數據庫 - 操作系統 - 游戲開發 - JS - Android - MySql - Redis - MongoDB - Win8 - Shell編程 - DOS命令 - jQuery - CSS樣式 - Python - Perl

Access - Oracle - DB2 - SQLServer - MsSql2008 - MsSql2005 - Sqlite - PostgreSQL - node.js - extjs - JavaScript vbs - Powershell - Ruby

JavaScript中Require調用js的實例分享

在我最初開始寫 JavaScript 函數時,通常是這樣的:

function fun1() {
 // some code here
}
function fun2() {
 // some other code here
}
...

函數全寫在全局環境中,項目很小時,通常不會有什么沖突問題。

但代碼多了后,漸漸就發現,函數名稱(英文詞匯)有點不夠用了。于是引入命名空間的概念,開始模塊化代碼。

命名空間下的函數

在命名空間下,我的代碼這樣寫:

var com = com || {};
com.zfanw = com.zfanw || {};
com.zfanw.module1 = (function() {
 // some code here
 return {
 func1: func1,
 ...
 };
}());
com.zfanw.module2 = (function() {
 // some other code here
 return {
 func1: func1,
 ...
 };
}());
...

本著要面向對象的原則,執行函數通常我要這么寫的:

com.zfanw.module1.func1.apply({},['arg1',arg2]);
...

當然,為了少打些字符,我還會在閉包中導入1公共 API 接口:www.09412140.buzz

(function($, mod1) {
 // some code here
 mod1.func1.apply({},['arg1',arg2]);
}(jQuery, com.zfanw.module1));
...
 

至此,代碼沖突的可能性已經很小,但代碼依賴的問題,多腳本文件管理、阻塞的問題,漸漸浮出水面 ? 命名空間的辦法開始捉急。

于是 Require.js2 出場。

Require.js

首先了解下 require.js 里模塊的概念3:

A module is different from a traditional script file in that it defines a well-scoped object that avoids polluting the global namespace. It can explicitly list its dependencies and get a handle on those dependencies without needing to refer to global objects, but instead receive the dependencies as arguments to the function that defines the module.

簡單地說,有兩點,一、模塊作用域自成一體,不污染全局空間;二、模塊指明依賴關系,并且依賴是通過參數傳遞的形式導入的,無需通過全局對象引用 ? 依賴同樣不污染全局空間。

定義模塊

與上面的老長的命名空間方式不同,require.js 用全局方法 define 來定義模塊,形式如下:

define(id?, dependencies?, factory); // ? 表示可選項
 

我且把模塊分兩種。

無依賴的模塊

假如一個模塊并不依賴其他模塊,那么定義起來是很簡單的,比如模塊 hello 放在 hello.js 文件中:

define(function() {
 // some code here
 return {
 // some public api
 };
});
 

有依賴的模塊

有依賴的模塊要稍稍復雜點,define 時,我們需要羅列出模塊的依賴情況:

define(['jquery'], function($) { // 比如這個模塊,代碼的執行依賴 jQuery,require.js 會先加載 jquery 模塊代碼,并加以執行,然后將依賴模塊 以 $ 的參數形式傳入回調函數中,回調函數將執行結果注冊為模塊
 // maybe some code here
 return {
 // some public api
 };
});
 

這里,依賴中的 'jquery' 是模塊相對于 baseUrl 的路徑,等效于模塊 ID。

現在,再回過頭,看看上面寫過的閉包中導入公共 API 的代碼,跟 define 函數做個對比:

(function($, mod1) {
 // some code here
 mod1.func1.apply({},['arg1',arg2]);
}(jQuery, com.zfanw.module1));

這段代碼里,我同樣把 jQuery 導入了,在閉包里,我同樣是通過 $ 這個外部傳入的參數來訪問 jQuery。可以說,它「定義依賴」的方式跟 define 方法很相似,不同的是,define 導入的 jquery 不是全局變量,所以不會污染全局環境。

關于模塊名稱

define 函數有三個參數,第一個 id 即模塊名稱,這個名稱的格式是相對于 baseUrl 的路徑除去文件格式,比如 baseUrl 為 js 目錄,一個模塊放在 js/libs/hi.js 里,則如果名稱是這樣定義的:

define('libs/hi', ['jquery'], function($){......});
 

這樣的定義形式的好處是,模塊不可能沖突,因為同一目錄下不允許同名文件。但也因此 require.js 建議我們不要設置模塊名稱,因為設置了 ‘libs/hi' 的模塊名稱后,模塊就必須放在 js/libs 目錄下的 hi.js 文件中,要移動位置的話,模塊名稱要跟著改變。至于后期利用 r.js 優化時生成了模塊名稱,那已經是另外一回事。

使用模塊

在定義好「有依賴」、「沒依賴」的各種模塊后,我們該怎么用它?Require.js 提供了一個函數,require(與 requirejs 等效)。

require 函數加載依賴并執行回調,與 define 不同的是,它不會把回調結果4注冊成模塊:

require(['jquery'], function($) { // 這個函數加載 jquery 依賴,然后執行回調代碼
 console.log($);
});
 

舉一個簡單的例子。我有一個文件夾,文件結構如下:

index.html
 js/
  main.js
  require.js
  jquery.js
 

這里 jquery.js 已經注冊為 AMD 模塊,則 HTML 文件里這樣引用 require.js:

<script src="js/require.js" data-main="js/main"></script>

require.js 會檢查 data-main 屬性值,這里是 js/main,根據設定,它會加載 js 目錄下的 main.js 文件。

main.js 文件里,我只干一件事,用 jQuery 方法取得當前窗口的寬度:

require(['jquery'], function($) {
 var w = $(window).width();
 console.log(w);
});

執行代碼就這么簡單。

非 AMD 規范的模塊

但事情遠沒有我們想像中那么美好,AMD 只是一種社區規范,并非標準,而且在它出現以前,已經有各種各樣的流行庫存在,更不用說我們自己早期寫的代碼,所以我們一定會碰上一堆非 AMD 規范的模塊。為了讓 require.js 能夠加載它們,并且自動識別、載入依賴,我們有兩種選擇,一、給它們全穿上一個叫 define 的函數;二、使用 Require.js 提供的配置選項 shim,曲線救國。

比如我手上一個項目,因為某種原因,還在用 jQuery 1.4.1 版本,而 jQuery 是從1.7版本開始才注冊為 AMD 模塊的,我要在 require.js 中使用,就需要先做 shim:

require.config({
 shim: {
  'jquery-1.4.1': { // <= 這個是相對于 main.js 的路徑www.45it.com
   exports: 'jQuery' // <= 這個值需要稍加注意,稍后會提及
  },
  'libs/jquery-throttle-debounce.min': { // <= jQuery 插件
   deps: ['jquery-1.4.1'] //無需 exports,因為我們只是在增強 jQuery 功能
  }
 },
});
require(['jquery-1.4.1', 'libs/jquery-throttle-debounce.min'], function($){
 console.log($.debounce);
});

寫完 shim,發現 jquery-1.4.1、libs/jquery-throttle-debounce.min 這樣的名稱有點長。這里我們又有兩種選擇,一是直接打開修改 js 文件名,或者使用 require.js 提供的配置項 paths 給模塊 ID 指定對應的真實文件路徑:

require.config({
 paths: {
  'jquery': 'jquery-1.4.1', // <= 模塊 jquery 指向 js/jquery-1.4.1.js 文件
  'debounce': 'libs/jquery-throttle-debounce.min'
 },
 shim: {
  'jquery': {
   exports: '$'
  },
  'debounce': {
   deps: ['jquery']
  }
 }
});
require(['jquery', 'debounce'], function($){
 console.log($.debounce);
});

這樣,引用起來就方便多了。

另外,需要注意 shim 中的 exports 項,它的概念更接近 imports,即把全局變量導入。我們如果把 exports 值改成非全局變量名,就會導致傳入回調的對象變成 undefined,舉個例子:

require.config({
 paths: {
  'jquery': 'jquery-1.4.1',
 },
 shim: {
  'jquery': {
   exports: 'hellojQuery' // 這里我把 exports 值設置為 jQuery/$ 以外的值
  }
 }
});
require(['jquery'], function($){
 console.log($);// 這里,會顯示 undefined
});
 

其他模塊在做 shim 時同理,比如 underscore 需要 exports 成 _。

Require.js 的好處

說了這么多,Require.js 到底有什么好處?

并行加載

我們知道,<script></script> 標簽會阻塞頁面,加載 a.js 時,后面的所有文件都得等它加載完成并執行結束后才能開始加載、執行。而 require.js 的模塊可以并行下載,沒有依賴關系的模塊還可以并行執行,大大加快頁面訪問速度。

不愁依賴

在我們定義模塊的時候,我們就已經決定好模塊的依賴 ? c 依賴 b,b 又依賴 a。當我想用 c 模塊的功能時,我只要在 require函數的依賴里指定 c:

require(['c'], function(c) {...});

至于 c 依賴的模塊,c 依賴的模塊的依賴模塊… 等等,require.js 會幫我們打理。

而傳統的 script 辦法,我們必須明確指定所有依賴順序:

<script src="js/a.js"></script>
 <script src="js/b.js"></script>
 <script src="js/c.js"></script>

換句話說,傳統的 script 方法里,我們極可能要靠記憶或者檢查模塊內容這種方式來確定依賴 ? 效率太低,還費腦。

減少全局沖突

通過 define 的方式,我們大量減少了全局變量,這樣代碼沖突的概率就極小極小 ? JavaScript 界有句話說,全局變量是魔鬼,想想,我們能減少魔鬼的數量,我想是件好事。

關于全局變量

有一點需要說明的是,require.js 環境中并不是只有 define 和 require 幾個全局變量。許多庫都會向全局環境中暴露變量,以 jQuery 為例,1.7版本后,它雖然注冊自己為 AMD 模塊,但同時也向全局環境中暴露了 jQuery 與 $。所以以下代碼中,雖然我們沒有向回調函數傳入一份引用,jQuery/$ 同樣是存在的:

require(['jquery'], function(){
 console.log(jQuery);
 console.log($);
});
 

以上這篇JavaScript中Require調用js的實例分享就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持積木網。

JS+CSS實現網頁加載中的動畫效果
本文實例為大家分享了JS實現網頁加載中效果的具體代碼,供大家參考,具體內容如下需要材料:一張loading動畫的gif圖片基本邏輯:模態框遮罩+loading.gi

淺析Javascript中雙等號(==)隱性轉換機制
在Javascript中判斷相等關系有雙等號(==)和三等號(===)兩種。其中雙等號(==)是值相等,而三等號(===)是嚴格相等(值及類型是否完全相等)。因此有幾個常

js通過Date對象實現倒計時動畫效果
js通過Date對象實現倒計時效果,具體內容如下!DOCTYPEhtmlhtmllang="en"headmetacharset="UTF-8"title倒計時動畫/titlestylediv{text-align:center;height:100px;line-height:100px;}/styles

本周排行

更新排行

強悍的草根IT技術社區,這里應該有您想要的! 友情鏈接:b2b電子商務
Copyright © 2010 Gimoo.Net. All Rights Rreserved  京ICP備05050695號
36选7走势图大全 股票指数和指数基金的区别 河内一分彩走势图 中国股票指数2018走势 北京快乐彩8 山西福彩十一选五开奖结果 大乐透手机版软件 qq新快3 新兴铸管股票推荐 江西多乐彩11选五今日开奖号码 股票大盘走势图 手机能玩的时时彩平台 河南快三和值走势图一定牛 股票配资平台是合法的么 重庆农场水果走势图 黑龙江十一选五结果 七星彩开奖结果app