JavaScript での Require 呼び出し js の例

小云云
リリース: 2018-01-02 09:53:21
オリジナル
1021 人が閲覧しました

この記事では主に、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.jb51.net

(function($, mod1) {
 // some code here
 mod1.func1.apply({},['arg1',arg2]);
}(jQuery, com.zfanw.module1));
...
ログイン後にコピー

この時点では、コードの競合の可能性は非常に小さいですが、コードの依存関係の問題、マルチ-スクリプト ファイルの管理、およびブロッキングの問題により、名前空間のアプローチが失敗し始めていることが徐々に明らかになりました。

それで Require.js2 が表示されます。

Require.js

まず、require.js 3 のモジュールの概念を理解してください。

モジュールは、グローバル名前空間の汚染を回避する適切なスコープのオブジェクトを定義するという点で、従来のスクリプト ファイルとは異なります。明示的にリストすることができます。グローバル オブジェクトを参照する必要なく、その依存関係を取得し、それらの依存関係のハンドルを取得します。代わりに、モジュールを定義する関数への引数として依存関係を受け取ります。

簡単に言うと、2 つのポイントがあります。1 つは、モジュールのスコープが自己であることです。含まれており、グローバル空間を汚染しません。 2. モジュールは依存関係を指定し、依存関係はグローバル オブジェクトを参照する必要なく、パラメーターの受け渡しによってインポートされます。依存関係もグローバル空間を汚染しません。

モジュールを定義する

上記の長い名前空間メソッドとは異なり、require.js はグローバル メソッドdefineを使用して、次の形式でモジュールを定義します:

define(id?, dependencies?, factory); // ? 表示可选项
ログイン後にコピー

モジュールを 2 つのタイプに分けてみましょう。

依存関係のないモジュール

モジュールが他のモジュールに依存しない場合、定義は非常に簡単です。たとえば、モジュール hello は hello.js ファイルに配置されます:

define(function() {
 // some code here
 return {
 // some public api
 };
});
ログイン後にコピー

依存関係のあるモジュール

依存関係 もう少し複雑にするには、定義するときにモジュールの依存関係をリストする必要があります:

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 もインポートし、クロージャで、またアクセスします。 $external パラメータを介して jQuery を実行します。 「依存関係を定義する」方法は、define メソッドに非常に似ていると言えます。違いは、define によってインポートされた jquery がグローバル変数ではないため、グローバル環境を汚染しないことです。

モジュール名について

define関数には3つのパラメータがあります。最初のidは、ファイル形式を除いたbaseUrlのパスに相対的なものです。名前が次のように定義されている場合、モジュールは 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 モジュールとして登録されており、次に require.js が次のように HTML ファイルで参照されます:

<script src="js/require.js" data-main="js/main"></script>
ログイン後にコピー

require.js は data-main をチェックします属性値、ここでは js /main です。設定に従って、js ディレクトリに main.js ファイルがロードされます。

main.js ファイルで行うことは 1 つだけです。jQuery メソッドを使用して現在のウィンドウの幅を取得します。

require(['jquery'], function($) {
 var w = $(window).width();
 console.log(w);
});
ログイン後にコピー

コードの実行は非常に簡単です。

非 AMD 標準モジュール

しかし、状況は私たちが想像していたほど良くありません。AMD は標準ではなく単なるコミュニティ仕様であり、私たちのコードは言うまでもなく、それが登場する前にすでにさまざまな人気のあるライブラリがありました。は早い段階で作成したため、AMD 以外の標準モジュールが大量に登場することは間違いありません。 require.js がそれらをロードし、依存関係を自動的に識別してロードできるようにするには、2 つのオプションがあります。1 つ目は、define という関数をすべてに与えることです。2 つ目は、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: &#39;jQuery&#39; // <= 这个值需要稍加注意,稍后会提及
  },
  &#39;libs/jquery-throttle-debounce.min&#39;: { // <= jQuery 插件
   deps: [&#39;jquery-1.4.1&#39;] //无需 exports,因为我们只是在增强 jQuery 功能
  }
 },
});
require([&#39;jquery-1.4.1&#39;, &#39;libs/jquery-throttle-debounce.min&#39;], function($){
 console.log($.debounce);
});
ログイン後にコピー

写完 shim,发现 jquery-1.4.1、libs/jquery-throttle-debounce.min 这样的名称有点长。这里我们又有两种选择,一是直接打开修改 js 文件名,或者使用 require.js 提供的配置项 paths 给模块 ID 指定对应的真实文件路径:

require.config({
 paths: {
  &#39;jquery&#39;: &#39;jquery-1.4.1&#39;, // <= 模块 jquery 指向 js/jquery-1.4.1.js 文件
  &#39;debounce&#39;: &#39;libs/jquery-throttle-debounce.min&#39;
 },
 shim: {
  &#39;jquery&#39;: {
   exports: &#39;$&#39;
  },
  &#39;debounce&#39;: {
   deps: [&#39;jquery&#39;]
  }
 }
});
require([&#39;jquery&#39;, &#39;debounce&#39;], function($){
 console.log($.debounce);
});
ログイン後にコピー

这样,引用起来就方便多了。

另外,需要注意 shim 中的 exports 项,它的概念更接近 imports,即把全局变量导入。我们如果把 exports 值改成非全局变量名,就会导致传入回调的对象变成 undefined,举个例子:

require.config({
 paths: {
  &#39;jquery&#39;: &#39;jquery-1.4.1&#39;,
 },
 shim: {
  &#39;jquery&#39;: {
   exports: &#39;hellojQuery&#39; // 这里我把 exports 值设置为 jQuery/$ 以外的值
  }
 }
});
require([&#39;jquery&#39;], 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($);
});
ログイン後にコピー

相关推荐:

a标签不能调用js方法的问题

JS调用PHP和PHP调用JS的方法示例

iframe子父页面调用js函数示例

以上がJavaScript での Require 呼び出し js の例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!