Module モジュラー プログラミングの利点 (概要の共有)

WBOY
リリース: 2022-08-08 16:06:56
転載
2384 人が閲覧しました

この記事では、javascript に関する関連知識を提供します。主に Module モジュラー プログラミングの利点を紹介します。フロントエンド関数がますます複雑になるにつれて、フロントエンド コードもますます拡張されます。メンテナンスコストを削減し、コードの再利用性を向上させるためには、フロントエンドのモジュール化が不可欠です。一緒に見ていきましょう。皆様のお役に立てれば幸いです。

Module モジュラー プログラミングの利点 (概要の共有)

[関連する推奨事項: JavaScript ビデオ チュートリアル Web フロントエンド ]

バックグラウンド

フロントエンドの機能がますます複雑になるにつれ、フロントエンドのコードは日々増大しており、メンテナンスコストを削減し、コードの再利用性を向上させるためには、フロントエンドのモジュール化が不可欠です。

すべての js ファイルが 1 つの HTML に導入されると、次のような悪影響が生じます:

  • リクエストが多すぎます。まず第一に、複数のモジュールに依存する必要があるため、複数のリクエストが送信され、リクエストが多すぎます

  • 依存関係の曖昧さ。それらの具体的な依存関係が何であるかはわかりません。つまり、それらの間の依存関係が理解できないため、読み込みシーケンスでエラーが発生しやすくなります。

  • メンテナンスが難しい。上記の 2 つの理由によりメンテナンスが困難になり、1 つのことが全身に影響を及ぼし、プロジェクトに重大な問題を引き起こす可能性が非常に高くなります。

モジュールの概念は、webpack で次のように定義されます。

モジュール式プログラミングでは、開発者はプログラムを個別の機能ブロック (個別のチャンク) に分解します。機能の)、モジュールと呼ばれます。各モジュールの接触面は完全なプログラムよりも小さいため、検証、デバッグ、テストが容易になります。適切に作成されたモジュールは、確実な抽象化とカプセル化の境界を提供し、アプリケーション内の各モジュールが一貫した設計と明確な目的を持つようにします。

モジュールは、単一の責任を持ち、互いに独立しており、結合度が低く、凝集性が高く、置換可能である個別の機能ブロックである必要があります。

モジュール性の概念

モジュール化は、複雑なシステムをより管理しやすいモジュールに分解する方法であり、システム コードを単一責任の一連のモジュールに分割できます。高度に分離され、交換可能なモジュールを使用すると、システムの一部の変更が他の部分にどのような影響を与えるかが明らかになり、システムの保守性がよりシンプルかつ容易になります。

モジュール化は、複雑なシステムを独立したモジュールに分解することできめ細かい制御を実現する分割統治の考え方であり、複雑なシステムの保守と管理に非常に有益です。モジュール性はコンポーネント化の基礎でもあり、今日の多彩なフロントエンドの世界の前提条件でもあります。

モジュール化が必要な理由

フロントエンド開発と他の開発作業の主な違いは、フロントエンドが多言語およびマルチレベルに基づいていることです。コーディングと組織化の作業、製品の配信はブラウザに基づいています。これらのリソースは、増分読み込みによってブラウザに実行されます。開発環境でこれらの断片化されたコードとリソースを整理し、ブラウザ側で迅速かつエレガントに読み込まれるようにするにはどうすればよいでしょうか?アップデートするにはモジュラーシステムが必要です。

モジュール性の利点

  • 保守性

    。モジュールは独立しているため、適切に設計されたモジュールでは外部コードの依存性が低くなり、独立して更新および改善できます。

  • 名前空間

    。 JavaScript では、変数がトップレベル関数の外で宣言されている場合、その変数はグローバルに使用可能になります。したがって、名前の競合が偶発的に発生することがよくあります。モジュール開発を使用して変数をカプセル化すると、地球環境の汚染を回避できます。

  • コードを再利用します

    。以前に作成したプロジェクトから新しいプロジェクトにコードをコピーしたいことがありますが、これは問題ありませんが、より良い方法は、モジュール参照を通じてコード ベースの重複を避けることです。モジュールを更新した後、そのモジュールを参照するすべてのプロジェクトを同時に更新し、バージョン番号を指定することで、API の変更によるトラブルを回避できます。

  • モジュール化の簡単な歴史

1. 最も単純かつ大雑把な方法

function fn1(){
  // ...
}
function fn2(){
  // ...
}
ログイン後にコピー

スクリプト タグを使用してファイルを導入し、関連する関数を呼び出します。これには依存関係の順序を手動で管理する必要があるため、名前の競合が発生しやすくなり、全体的な状況が悪化する可能性があり、プロジェクトの複雑さが増すにつれて、メンテナンスのコストもますます高くなります。

2. オブジェクトを使用して名前空間をシミュレートする

var output = {
  _count: 0,
  fn1: function(){
    // ...
  }
}
ログイン後にコピー

これにより、上記の地球規模の汚染問題を解決できます。名前空間にはある程度の意味がありますが、プロジェクトの複雑さが増すにつれて、より多くの名前空間が必要になります。このような管理が必要なオブジェクトは非常にたくさんありますが、何よりも問題となるのは、それらに名前を付けることです。最も重要なことは、内部プロパティに直接アクセスして変更できることです。

3. 終了

var module = (function(){
  var _count = 0;
  var fn1 = function (){
    // ...
  }
  var fn2 = function fn2(){
    // ...
  }
  return {
    fn1: fn1,
    fn2: fn2
  }
})()
module.fn1();
module._count; // undefined
ログイン後にコピー

这样就拥有独立的词法作用域,内存中只会存在一份 copy。这不仅避免了外界访问此 IIFE 中的变量,而且又不会污染全局作用域,通过 return 暴露出公共接口供外界调用。这其实就是现代模块化实现的基础。

4. 更多

还有基于闭包实现的松耦合拓展、紧耦合拓展、继承、子模块、跨文件共享私有对象、基于 new 构造的各种方式,这种方式在现在看来都不再优雅。

// 松耦合拓展
// 这种方式使得可以在不同的文件中以相同结构共同实现一个功能块,且不用考虑在引入这些文件时候的顺序问题。
// 缺点是没办法重写你的一些属性或者函数,也不能在初始化的时候就是用module的属性。
var module = (function(my){
  // ...
  return my
})(module || {})
// 紧耦合拓展(没有传默认参数)
// 加载顺序不再自由,但是可以重载
var module = (function(my){
  var old = my.someOldFunc
  
  my.someOldFunc = function(){
    // 重载方法,依然可通过old调用旧的方法...
  }
  return my
})(module)
ログイン後にコピー

实现模块化的方案规范总览

历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的import,甚至就连 CSS 都有@import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。

在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

目前实现模块化的规范主要有:

  • CommonJS

CommonJS 是以在浏览器环境之外构建 JavaScript 生态系统为目标而产生的项目,比如在服务器和桌面环境中。

采用同步加载模块的方式,也就是说只有加载完成,才能执行后面的操作。CommonJS 代表:Node 应用中的模块,通俗的说就是你用 npm 安装的模块。

它使用 require 引用和加载模块,exports 定义和导出模块,module 标识模块。使用 require 时需要去读取并执行该文件,然后返回 exports 导出的内容。

  • CMD

CMD(Common Module Definition)

CMD是SeaJS在推广过程中生产的对模块定义的规范,在Web浏览器端的模块加载器中,SeaJS与RequireJS并称,SeaJS作者为阿里的玉伯。

CMD规范专门用于浏览器端,模块的加载是异步的,模块使用时才会加载执行。CMD规范整合了CommonJS和AMD规范的特点。在 Sea.js 中,所有 JavaScript 模块都遵循 CMD模块定义规范。

  • AMD

AMD(Asynchronous Module Definition)

异步模块定义,所谓异步是指模块和模块的依赖可以被异步加载,他们的加载不会影响它后面语句的运行。有效避免了采用同步加载方式中导致的页面假死现象。AMD代表:RequireJS。

AMD一开始是CommonJS规范中的一个草案,全称是Asynchronous Module Definition,即异步模块加载机制。后来由该草案的作者以RequireJS实现了AMD规范,所以一般说AMD也是指RequireJS。

RequireJS是一个工具库,主要用于客户端的模块管理。它的模块管理遵守AMD规范,RequireJS的基本思想是,通过define方法,将代码定义为模块;通过require方法,实现代码的模块加载。

  • ES6模块

ES6模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。所以说ES6是编译时加载,不同于CommonJS的运行时加载(实际加载的是一整个对象),ES6模块不是对象,而是通过export命令显式指定输出的代码,输入时也采用静态命令的形式。

ES6 的模块自动采用严格模式,不管你有没有在模块头部加上”use strict”;。

严格模式主要有以下限制。

  • 变量必须声明后再使用

  • 函数的参数不能有同名属性,否则报错

  • 不能使用with语句

  • 不能对只读属性赋值,否则报错

  • 不能使用前缀 0 表示八进制数,否则报错

  • 不能删除不可删除的属性,否则报错

  • 不能删除变量delete prop,会报错,只能删除属性delete global[prop]

  • eval不会在它的外层作用域引入变量

  • eval和arguments不能被重新赋值

  • arguments不会自动反映函数参数的变化

  • 不能使用arguments.callee

  • 不能使用arguments.caller

  • 禁止this指向全局对象

  • fn.caller および fn.arguments を使用して関数呼び出しのスタックを取得することはできません

  • 追加された予約語 (protected、static、interface など)

モジュールは上記の制限に従う必要があります。

【関連する推奨事項: JavaScript ビデオ チュートリアル Web フロントエンド ]

以上がModule モジュラー プログラミングの利点 (概要の共有)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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