簡単なJavaScriptクラスフレームワークの紹介_基礎知識
現在進行中の JavaScript 本を執筆する際、私は JavaScript 継承システムにかなりの時間を費やし、その過程で古典的なクラス継承をシミュレートするためのさまざまなソリューションを研究しました。これらの技術的ソリューションの中で、base2 と Prototype の実装は私が最も賞賛するものです。
これらのソリューションから、イデオロギー的な意味を持つフレームワークを抽出する必要があります。そのフレームワークは、シンプルで再利用可能で、依存関係から独立している必要があります。使用例は次のとおりです:
var Person = Class. extend ( { init: function (isDancing ) { this. dancing = isDancing; }, dance: function ( ) { return this. dancing; } } ); var Ninja = Person.extend({ init: function(){ this._super( false ); }, dance: function(){ // Call the inherited version of dance() return this._super(); }, swingSword: function(){ return true; } }); var p = new Person(true); p.dance(); // => true var n = new Ninja(); n.dance(); // => false n.swingSword(); // => true // Should all be true p instanceof Person && p instanceof Class && n instanceof Ninja && n instanceof Person && n instanceof Class
注意すべき点がいくつかあります:
- コンストラクターは単純である必要があります (init 関数を通じて実装されます)。
- 新しく定義されたアナロジーは、既存のクラス から継承する必要があります。
- すべての「クラス」は祖先クラス Class を継承するため、新しいクラスを作成する場合、そのクラスは Class のサブクラスである必要があります。
- 最も難しい点: 親クラスのオーバーライドされたメソッドは (構成コンテキストを通じて) アクセス可能でなければなりません。
- 上の例では、 Person 親クラスの init() メソッドと dance() メソッドが this._super() を通じて呼び出されていることがわかります。
結果には非常に満足しています。クラス定義が構造化され、単一継承が維持され、スーパークラス メソッドを呼び出すことができました。
単純なクラスの作成と継承
以下はその実装です (読みやすく、コメントも付いています)。約 25 行です。ご提案を歓迎いたします。
/* Simple JavaScript Inheritance * By John Resig http://ejohn.org/ * MIT Licensed. */ // Inspired by base2 and Prototype ( function ( ) { var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; // The base Class implementation (does nothing) this.Class = function(){}; // Create a new Class that inherits from this class Class.extend = function(prop) { var _super = this.prototype; // Instantiate a base class (but only create the instance, // don't run the init constructor) initializing = true; var prototype = new this(); initializing = false; // Copy the properties over onto the new prototype for (var name in prop) { // Check if we're overwriting an existing function prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = _super[name]; // The method only need to be bound temporarily, so we // remove it when we're done executing var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } // The dummy class constructor function Class() { // All construction is actually done in the init method if ( !initializing && this.init ) this.init.apply(this, arguments); } // Populate our constructed prototype object Class.prototype = prototype; // Enforce the constructor to be what we expect Class.prototype.constructor = Class; // And make this class extendable Class.extend = arguments.callee; return Class; }; })();
このうち、「初期化する/initを呼ばない」と「_superメソッドの作成」が最も難しいです。次に、誰もがその実装メカニズムをよりよく理解できるように、これについて簡単に紹介します。
初期化
関数プロトタイプの継承方法を説明するために、まず従来の実装プロセスを見てみましょう。これは、サブクラスのプロトタイプ属性が親クラスのインスタンスを指すようにするというものです。以下に示すように:
function Person ( ) { } function Ninja ( ) { } Ninja. prototype = new Person ( ); // Allows for instanceof to work: (new Ninja()) instanceof Person
ただし、ここでの難しい点は、「instanceOf」の効果だけを取得したいだけであり、Person をインスタンス化し、そのコンストラクターを呼び出すという結果は必要ないことです。これを防ぐには、コード内で初期化する bool パラメータを設定します。この値は、親クラスがインスタンス化され、子クラスのプロトタイプ プロパティに設定された場合にのみ true になります。この処理の目的は、実際のインスタンス化中のコンストラクターの呼び出しとデザインの継承の違いを区別し、実際のインスタンス化中に init メソッドを呼び出すことです。
if ( !initializing ) this.init.apply(this, arguments);
スーパーメソッド
継承を使用する場合、最も一般的な要件は、サブクラスがスーパークラスのオーバーライドされたメソッドにアクセスできることです。この実装では、最終的な解決策は、スーパークラス メソッドを指し、サブクラス メソッドでのみアクセスできる一時メソッド (._super) を提供することです。
var Person = Class. extend ( { init: function (isDancing ) { this. dancing = isDancing; } } ); var Ninja = Person.extend({ init: function(){ this._super( false ); } }); var p = new Person(true); p.dancing; // => true var n = new Ninja(); n.dancing; // => false
この機能を実装するには、いくつかの手順が必要です。まず、extend を使用して、基本的な Person インスタンス (その構築プロセスは上で説明したクラス インスタンス) をリテラル オブジェクト (Person.extend() の関数パラメーター) とマージします。マージ プロセス中に、簡単なチェックが行われました。まず、マージされる属性が関数であるかどうかをチェックし、そうである場合は、上書きされるスーパークラス属性も関数であるかどうかをチェックします。両方のチェックが true の場合、このプロパティに対して _super メソッドを準備する必要があります。
追加されたスーパー メソッドをカプセル化するために、匿名クロージャ (関数オブジェクトを返す) がここで作成されることに注意してください。実行環境を維持する必要があるため、関数の実行後にリセットされるように古い this._super を保存する必要があります (同じ名前を付けたくない場合)。誤ってオブジェクト ポインタを失う) 予測できない問題。
次に、スーパー クラス内のオーバーライドされたメソッドのみを指す新しい _super メソッドを作成します。ありがたいことに、_super に変更を加えたりスコープを変更したりする必要はありません。関数の実行環境は関数呼び出しオブジェクト (ポインター this はスーパー クラスを指します) に応じて自動的に変更されるためです。
最後に、リテラル オブジェクトのメソッドを呼び出します。メソッドの実行中に This._super() が使用され、属性 _super が元の状態にリセットされ、関数が終了します。
同じ効果を達成する方法はたくさんあります (以前、super をそれ自体にバインドし、arguments.callee でアクセスするのを見てきました) が、この方法が使いやすさとシンプルさの特徴を最もよく反映していると感じます。
私が完成させた JavaScript プロトタイプに基づく多くの作品の中で、これは私が皆さんと共有するために公開した唯一のクラス継承実装計画です。私は、簡潔なコード (学習しやすく、継承しやすく、ダウンロードが少ない) を全員で議論できるようにする必要があると考えています。そのため、JavaScript クラスの構築と継承を学ぶ人にとって、この実装計画は良いスタートとなります。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Java フレームワークの商用サポートのコスト/パフォーマンスを評価するには、次の手順が必要です。 必要な保証レベルとサービス レベル アグリーメント (SLA) 保証を決定します。研究サポートチームの経験と専門知識。アップグレード、トラブルシューティング、パフォーマンスの最適化などの追加サービスを検討してください。ビジネス サポートのコストと、リスクの軽減と効率の向上を比較検討します。

PHP フレームワークの学習曲線は、言語熟練度、フレームワークの複雑さ、ドキュメントの品質、コミュニティのサポートによって異なります。 PHP フレームワークの学習曲線は、Python フレームワークと比較すると高く、Ruby フレームワークと比較すると低くなります。 Java フレームワークと比較すると、PHP フレームワークの学習曲線は中程度ですが、開始までの時間は短くなります。

軽量の PHP フレームワークは、サイズが小さくリソース消費が少ないため、アプリケーションのパフォーマンスが向上します。その特徴には、小型、高速起動、低メモリ使用量、改善された応答速度とスループット、および削減されたリソース消費が含まれます。 実際のケース: SlimFramework は、わずか 500 KB、高い応答性と高スループットの REST API を作成します。

ベンチマークによると、小規模で高性能なアプリケーションの場合、Quarkus (高速起動、低メモリ) または Micronaut (TechEmpower に優れた) が理想的な選択肢です。 SpringBoot は大規模なフルスタック アプリケーションに適していますが、起動時間とメモリ使用量が若干遅くなります。

明確で包括的なドキュメントを作成することは、Golang フレームワークにとって非常に重要です。ベスト プラクティスには、Google の Go コーディング スタイル ガイドなど、確立されたドキュメント スタイルに従うことが含まれます。見出し、小見出し、リストなどの明確な組織構造を使用し、ナビゲーションを提供します。スタート ガイド、API リファレンス、概念など、包括的で正確な情報を提供します。コード例を使用して、概念と使用法を説明します。ドキュメントを常に最新の状態に保ち、変更を追跡し、新機能を文書化します。 GitHub の問題やフォーラムなどのサポートとコミュニティ リソースを提供します。 API ドキュメントなどの実践的なサンプルを作成します。

アプリケーションのシナリオに基づいて最適な Go フレームワークを選択します。アプリケーションの種類、言語機能、パフォーマンス要件、エコシステムを考慮します。一般的な Go フレームワーク: Jin (Web アプリケーション)、Echo (Web サービス)、Fiber (高スループット)、gorm (ORM)、fasthttp (速度)。実際のケース: REST API (Fiber) の構築とデータベース (gorm) との対話。フレームワークを選択します。主要なパフォーマンスには fasthttp、柔軟な Web アプリケーションには Jin/Echo、データベース インタラクションには gorm を選択してください。

Go フレームワークの学習には、フレームワークへの過度の依存と柔軟性の制限という 5 つの誤解があります。フレームワークの規則に従わない場合、コードの保守が困難になります。古いライブラリを使用すると、セキュリティと互換性の問題が発生する可能性があります。パッケージを過度に使用すると、コード構造が難読化されます。エラー処理を無視すると、予期しない動作やクラッシュが発生します。

Go フレームワーク開発における一般的な課題とその解決策は次のとおりです。 エラー処理: 管理にはエラー パッケージを使用し、エラーを一元的に処理するにはミドルウェアを使用します。認証と認可: サードパーティのライブラリを統合し、資格情報を確認するためのカスタム ミドルウェアを作成します。同時処理: ゴルーチン、ミューテックス、チャネルを使用してリソース アクセスを制御します。単体テスト: 分離のために getest パッケージ、モック、スタブを使用し、十分性を確保するためにコード カバレッジ ツールを使用します。デプロイメントとモニタリング: Docker コンテナを使用してデプロイメントをパッケージ化し、データのバックアップをセットアップし、ログ記録およびモニタリング ツールでパフォーマンスとエラーを追跡します。
