ホームページ > 記事 > ウェブフロントエンド > JavaScript プロトタイプ プロトタイプchain_prototype
JavaScript のプロトタイプの概念は、この言葉の意味を適切に反映しています。C のプロトタイプのように、事前に宣言された概念として理解することはできません。
JavaScript のすべての関数型オブジェクトには、prototype 属性があります。プロトタイプ属性自体はオブジェクト型オブジェクトなので、このプロトタイプ オブジェクトに任意のプロパティやメソッドを追加することもできます。プロトタイプはオブジェクトの「プロトタイプ」であるため、この関数によって構築されるオブジェクトはこの「プロトタイプ」の特性を持つ必要があります。実際、コンストラクターのプロトタイプで定義されたすべてのプロパティとメソッドは、それが構築するオブジェクトを通じて直接アクセスし、呼び出すことができます。プロトタイプは、同様のオブジェクトのグループがプロパティとメソッドを共有するためのメカニズムを提供するとも言えます。
まず次のコードを見てみましょう。
function Person(name)
{
this.name = name; //オブジェクトの属性を設定します。各オブジェクトには独自の属性データがあります
};
person.prototype.SayHello = function() //SayHello メソッドを Person 関数のプロトタイプに追加します。
{
alert("こんにちは、" this.name);
}
var BillGates = new Person("Bill Gates") // BillGates オブジェクトを作成します
var SteveJobs = new Person("Steve Jobs"); //SteveJobs オブジェクトを作成します
BillGates.SayHello(); //BillGates オブジェクトを通じて SayHello メソッドを直接呼び出します
SteveJobs.SayHello(); SteveJobs オブジェクト SayHello メソッドに移動します。
alert(BillGates.SayHello == SteveJobs.SayHello); //2 つのオブジェクトは SayHello のプロトタイプを共有しているため、次のように表示されます。 true
プログラムを実行した結果、コンストラクターはプロトタイプで定義されており、メソッドは実際にオブジェクトを通じて直接呼び出すことができ、コードは共有されます。明らかに、メソッドをプロトタイプに設定する記述方法は、呼び出し形式に変更はありませんが、以前の記述方法と比較して、メソッドとクラスの関係を論理的に反映しています。コード。
それでは、マルチレベル型のコンストラクターはどうなるでしょうか?
もう一度次のコードを見てみましょう。
1 function Person(name) //base class constructionor
2 {
3 this.name = name
5 };
6 person.prototype.SayHello = function() //基本クラスのコンストラクターのプロトタイプにメソッドを追加します
7 {
8 alter("Hello, I'm " this.name); 🎜> 9 };
10
11 function Employee(name,給与) //サブクラス コンストラクター
12 {
13 person.call(this, name) //基本クラス コンストラクターを呼び出します。 >14 this.salary =給与;
15 };
16
17 Employee.prototype = new Person(); // サブクラス プロトタイプのプロトタイプとして基本クラス オブジェクトを作成します。 .
18
19 Employee.prototype.ShowMeTheMoney = function() //サブクラスのコンストラクターのプロトタイプにメソッドを追加します
20 {
21 alter(this.name " $" this.salary ) ;
22 };
23
24 var BillGates = new Person("Bill Gates") // 基本クラス Person
25 の BillGates オブジェクトを作成します var SteveJobs = new Employee("Steve Jobs" , 1234); //サブクラス Employee の SteveJobs オブジェクトを作成します
26
27 BillGates.SayHello(); // オブジェクトを通じてプロトタイプ メソッドを直接呼び出します
28 SteveJobs.SayHello(); //Pass サブクラス オブジェクトは基本クラス プロトタイプのメソッドを直接呼び出します。注意してください。
29 SteveJobs.ShowMeTheMoney(); // サブクラス オブジェクトを通じてサブクラス プロトタイプのメソッドを直接呼び出します。
30
31 alter(BillGates.SayHello == SteveJobs.SayHello); //プロトタイプ メソッドが共有されていることを示します
このコードの 17 行目は、基本クラス オブジェクトを構築し、それをサブクラス コンストラクターのプロトタイプとして設定します。これは非常に興味深いものです。この目的は 28 行目です。基本クラスのプロトタイプのメソッドは、サブクラス オブジェクトを通じて直接呼び出すこともできます。なぜこのようなことが可能なのでしょうか?
JavaScript では、プロトタイプによってオブジェクトがその富を共有できるようになるだけでなく、プロトタイプにはそのルーツや先祖をたどるという性質もあり、先祖の遺産を世代から世代へと受け継ぐことができることがわかりました。オブジェクトから属性を読み取るかメソッドを呼び出す場合、オブジェクト自体にそのような属性やメソッドがない場合は、それ自体に関連付けられているプロトタイプ オブジェクトに移動して検索します。プロトタイプに属性やメソッドがない場合は、先行するオブジェクトに移動します。プロトタイプ自体に関連付けられたプロトタイプを、見つかるまで、またはトレース プロセスが完了するまで検索します。
JavaScript 内部では、オブジェクトの属性とメソッドのトレース メカニズムが、いわゆるプロトタイプ チェーンを通じて実装されます。 new 演算子を使用してオブジェクトが構築されると、コンストラクターのプロトタイプ オブジェクトも新しく作成されたオブジェクトに割り当てられ、オブジェクトの組み込みプロトタイプ オブジェクトになります。オブジェクトの組み込みプロトタイプ オブジェクトは外部からは見えないようにする必要がありますが、一部のブラウザ (Firefox など) ではこの組み込みプロトタイプ オブジェクトにアクセスできますが、これはお勧めできません。組み込みプロトタイプ オブジェクト自体もオブジェクトであり、独自の関連付けられたプロトタイプ オブジェクトを持ち、いわゆるプロトタイプ チェーンを形成します。
プロトタイプ チェーンの最後には、オブジェクト コンストラクターのプロトタイプ属性によって指定されるプロトタイプ オブジェクトがあります。このプロトタイプ オブジェクトは、すべてのオブジェクトの最も古い祖先であり、すべてのオブジェクトが本質的に持つべき toString などのメソッドを実装します。 Function、Boolean、String、Date、RegExp などの他の組み込みコンストラクターのプロトタイプはすべてこの祖先から継承されていますが、それらはそれぞれ独自のプロパティとメソッドを定義しているため、子孫はそれぞれのクランの特性を示します。それらの特徴。
これは単なる「継承」ではないでしょうか?そう、これが「継承」、JavaScript特有の「プロトタイプ継承」です。
「原型継承」は優しくもあり、厳しい。プロトタイプ オブジェクトは、そのプロパティとメソッドを無私無欲に子供たちに提供し、子供たちに従うことを強制しないため、一部のいたずらな子供たちが自分の興味や趣味に応じて独立して行動できるようになります。この点において、典型的な主体は愛情深い母親です。ただし、どの子供も自分のやり方を貫くことができますが、他の子供の利益に影響を与える可能性があるため、プロトタイプ オブジェクトの既存のプロパティに触れることはできません。この観点から見ると、プロトタイプオブジェクトは厳格な父親のようなものです。これが何を意味するのかを理解するために、次のコードを見てみましょう。 Microsoft"; //プロトタイプ プロパティ
person.prototype.SayHello = function() //プロトタイプ メソッド
{
alert("こんにちは、" this.company の " this.name " );
};
var BillGates = new Person("Bill Gates");
BillGates.SayHello(); // プロトタイプを継承しているため、出力は次のようになります。 こんにちは、ビル ゲイツです。 🎜>var SteveJobs = new Person("Steve Jobs");
SteveJobs.company = "Apple" //プロトタイプの会社プロパティをカバーして、独自の会社プロパティを設定します
SteveJobs.SayHello = function () / /プロトタイプの SayHello メソッドをカバーして、独自の SayHello メソッドを実装しました。
{
alert("Hi, " this.name " like " this.company ",
}; >SteveJobs.SayHello(); //これらはすべて、それ自体でカバーされるプロパティとメソッドです、出力: こんにちは、Steve Jobs は Apple のようです、はははは
BillGates.SayHello() //SteveJobs の上書きは効果がありません。
オブジェクトは、プロトタイプ オブジェクトの場合でも、以前と同じように出力します。コンストラクター プロトタイプ オブジェクトは、上位層のコンストラクター プロトタイプ オブジェクトの既存のプロパティとメソッドをマスクすることもできます。このマスキングは実際にはオブジェクト自体に新しいプロパティとメソッドを作成するだけですが、これらのプロパティとメソッドはプロトタイプ オブジェクトの名前と同じです。 JavaScript は、この単純なマスキング メカニズムを使用してオブジェクトの「ポリモーフィズム」を実現します。これは、静的オブジェクト言語の仮想関数およびオーバーライドの概念と一致します。
しかし、静的オブジェクト言語よりもさらに魅力的なのは、プロトタイプ オブジェクトにいつでも新しいプロパティとメソッドを動的に追加できるため、基本クラスの機能を動的に拡張できることです。これは静的オブジェクト言語では想像するのが困難です。次のコードを見てみましょう:
function Person(name)
{
this.name = name;
};
person.prototype.SayHello = function() //オブジェクト定義メソッド
{
alert("こんにちは、" this.name);
var BillGates = new Person("Bill Gates"); >BillGates.SayHello();
person.prototype.Retire = function() //オブジェクト作成後にプロトタイプを動的に拡張するメソッド
{
alert("Poor " this.name ", bye bye ! ");
};
BillGates.Retire(); //動的に拡張されたメソッドは、以前に作成されたオブジェクトによってすぐに呼び出すことができます
Amitābha、プロトタイプの継承は実際にそのような魔法を実行できます。
プロトタイプの拡張
あなたは次のように考えるかもしれません。Object や Function などの JavaScript の組み込み関数のプロトタイプに新しいメソッドやプロパティを追加すると、拡張できるでしょうか。 JavaScriptの機能はどうなるのでしょうか?
それでは、おめでとうございます。わかりました!
今日の AJAX テクノロジの急速な発展に伴い、多くの成功した AJAX プロジェクトの JavaScript ランタイム ライブラリは、組み込み関数のプロトタイプ関数を大幅に拡張しました。たとえば、Microsoft の ASP.NET AJAX は、これらの組み込み関数とそのプロトタイプに多数の新機能を追加し、JavaScript の機能を強化します。
MicrosoftAjax.debug.js から抜粋したコードを見てみましょう。
String.prototype.trim = function String$trim() {
if (arguments.length !== 0) throw エラー。 parameterCount ();
return this.replace(/^s |s $/g, '');
}
このコードは組み込み String 関数のプロトタイプに拡張します。すべての String クラス オブジェクトには、trim メソッドが追加されました。この拡張機能を使用すると、将来、文字列の 2 つのセクション間の空白を削除したい場合、それを個別に処理する必要がなくなりました。どの文字列にもこの拡張機能があり、それを呼び出すだけで済むためです。便利。
もちろん、オブジェクトのプロトタイプにメソッドを追加する人はほとんどいません。アーキテクチャ内のすべてのオブジェクトで実際にこのメソッドが必要な場合を除き、メソッドを追加するとすべてのオブジェクトに影響するからです。
2 年前、AJAX クラス ライブラリの設計初期に、Microsoft は「クラス」をシミュレートするために「クロージャ」と呼ばれるテクノロジを使用しました。大まかなモデルは次のとおりです。
function person(firstName, lastName, age)
{
//プライベート変数:
var _firstName = firstName;
var _lastName = lastName; // パブリック変数:
this.age = age;
//メソッド:
this.getName = function()
{
return(firstName " " lastName); ;
this.SayHello = function()
{
alert("こんにちは、" firstName " " lastName)
};人( "ビル", "ゲイツ", 53);
var SteveJobs = 新しい 人("スティーブ", "ジョブズ", 53);
ビルゲイツ.SayHello(); ;
alert(BillGates.getName() " " BillGates.age);
alert(BillGates.firstName); //ここではプライベート変数にアクセスできません
明らかに、このモデルのクラス記述は次のようになります。 C# 言語 記述フォームは、コンストラクターでプライベート メンバー、パブリック プロパティ、および使用可能なメソッドを定義します。これは非常に洗練されています。特に、「クロージャ」メカニズムはプライベート メンバーの保護メカニズムをシミュレートでき、非常に美しいです。
いわゆる「クロージャ」とは、コンストラクタ本体に別の関数を対象オブジェクトのメソッド関数として定義し、そのオブジェクトのメソッド関数が外側の関数本体の一時変数を参照することです。これにより、ターゲット オブジェクトが存続期間中常にそのメソッドを維持できる限り、元のコンストラクター本体で使用される一時変数の値を間接的に維持できます。最初のコンストラクター呼び出しは終了し、一時変数の名前は消えていますが、変数の値はターゲット オブジェクトのメソッド内で常に参照でき、このメソッドを介してのみ値にアクセスできます。同じコンストラクターが再度呼び出された場合でも、新しいオブジェクトとメソッドのみが生成されます。新しい一時変数は新しい値にのみ対応し、最後の呼び出しからは独立しています。確かにとても賢いですね!
しかし、前に述べたように、オブジェクトごとにメソッドを設定するのは大きな無駄です。さらに、変数値を間接的に維持するメカニズムである「クロージャ」は、JavaScript のガベージ コレクターに問題を引き起こすことがよくあります。特にオブジェクト間の複雑な循環参照が発生した場合、ガベージコレクションの判定ロジックは非常に複雑になります。偶然にも、IE の初期バージョンでは JavaScript ガベージ コレクションでメモリ リークが発生しました。パフォーマンス テストにおける「クロージャ」モデルのパフォーマンスの低さと相まって、Microsoft は最終的に「クロージャ」モデルを放棄し、「プロトタイプ」モデルに切り替えました。ことわざにあるように、「得たものには必ず損失が伴います」。
プロトタイプ モデルでは、オブジェクトのメンバーを定義するコンストラクターが必要で、メソッドはコンストラクターのプロトタイプにアタッチされます。大まかな書き方は次のとおりです。
//コンストラクター
関数を定義します。 Person(name)
{
this.name = name; //コンストラクター内のメンバーを定義します
}; >/ /メソッドはコンストラクターのプロトタイプで定義されています
person.prototype.SayHello = function()
{
alert("Hello, I'm " this.name); ;
//サブクラスのコンストラクター
function Employee(name,給与)
{
person.call(this, name) //上位レベルのコンストラクターを呼び出します
this.salary =給与; //拡張メンバー
};
//サブクラス コンストラクターは、継承の概念を実現するために、最初に上位レベルのコンストラクターを使用してプロトタイプ オブジェクトを作成する必要があります
Employee.prototype = new Person() //必要なのはプロトタイプ メソッドのみであり、このオブジェクトのメンバーには意味がありません。
//サブクラス メソッドはコンストラクターでも定義されます
Employee.prototype.ShowMeTheMoney = function()
{
alert(this.name " $" this.salary);
var BillGates = 新しい人("ビル・ゲイツ");
ビルゲイツ.SayHello();
var SteveJobs = 新しい従業員("スティーブ・ジョブズ", 1234);
SteveJobs.ShowMeTheMoney();
プロトタイプ クラス モデルは実際のプライベート変数をシミュレートできませんが、クラスを定義するために 2 つの部分に分割する必要があり、あまり「エレガント」ではありません。ただし、メソッドはオブジェクト間で共有され、ガベージ コレクションの問題が発生せず、「クロージャ」モデルよりも優れたパフォーマンスを発揮します。ことわざにあるように、「失うものは必ず得られるものである」。
プロトタイプ モデルでクラス継承を実装するには、まずサブクラス コンストラクターのプロトタイプを親クラスのオブジェクト インスタンスに設定する必要があります。この親クラスのオブジェクト インスタンスを作成する目的は、上位のプロトタイプ メソッドを共有するプロトタイプ チェーンを形成することです。ただし、このインスタンス オブジェクトが作成されると、上位レベルのコンストラクターもオブジェクト メンバーをそれに設定します。これらのオブジェクト メンバーは継承には意味がありません。コンストラクターにパラメーターを渡していないにもかかわらず、値が未定義であるとはいえ、役に立たないメンバーをいくつか作成してしまい、これも無駄です。
ああ!世の中に完璧なものなどありません!
元型の真実
私たちが感無量だったそのとき、空に赤い光が輝き、吉祥の雲の中に観音菩薩が現れました。彼女が翡翠の浄化瓶を持ち、緑の柳の枝をはじき、蜜を数滴振りかけているのを見たとき、すぐに JavaScript に新しいオーラが与えられました。
観音様が撒いた蜜は、JavaScriptの世界ではブロックに凝縮され、「文法蜜」と呼ばれるものになりました。この構文の蜜により、私たちが書くコードがよりオブジェクト言語のように見えるようになります。
この「文法蜜」が何なのか知りたい場合は、注意深く聞いてください。
これらの文法を理解する前に、JavaScript でオブジェクトを構築するプロセスを確認する必要があります。
var anObject = new aFunction() の形式でオブジェクトを作成するプロセスは、実際には 3 つのステップに分割できることはすでにわかっています。最初のステップは新しいオブジェクトを作成し、2 番目のステップはビルドされたオブジェクトを設定することです。 -in オブジェクトのプロトタイプ オブジェクトをコンストラクターに渡します。関数プロトタイプによって参照されるプロトタイプ オブジェクト。3 番目のステップでは、このオブジェクトをパラメーターとして使用してコンストラクターを呼び出し、メンバーの設定などの初期化作業を完了します。オブジェクトの作成後、オブジェクトに対するアクセスと操作は、オブジェクト自体とプロトタイプ チェーン上のオブジェクトの文字列にのみ関連し、コンストラクターとは何の関係もありません。つまり、コンストラクターはオブジェクト作成時にプロトタイプオブジェクトの導入と初期化の役割だけを果たします。
では、自分でオブジェクトをプロトタイプとして定義し、そのプロトタイプ上にクラスを記述し、そのプロトタイプを新しく作成したオブジェクトに設定して、そのオブジェクトのクラスとして扱うことができるでしょうか?このプロトタイプのメソッドをコンストラクターとして使用して、新しく作成されたオブジェクトを初期化できますか?たとえば、次のようなプロトタイプ オブジェクトを定義します。
var person = //オブジェクトをプロトタイプ クラスとして定義します
{
Create: function(name, age) //これはコンストラクター関数として使用されます
{
this.name = name;
this.age = 年齢;
SayHello: function() // メソッドを定義します
{
alert("こんにちは、私は " this.name);
},
HowOld: function() //メソッド
{
alert(this.name " は " this.age " 歳です。") を定義します。 ;
}
}
この JSON の書き方は C# クラスのように見えます。コンストラクターとさまざまなメソッドの両方があります。何らかの形式でオブジェクトを作成し、そのオブジェクトの組み込みプロトタイプを上記の「クラス」オブジェクトに設定できる場合、それはそのクラスのオブジェクトを作成するのと同じではないでしょうか。
しかし、残念ながら、オブジェクトの組み込みプロトタイプ プロパティにはほとんどアクセスできません。一部のブラウザはオブジェクトの組み込みプロトタイプにアクセスできますが、これによりユーザーが使用しなければならないブラウザが制限されるだけです。これもほぼ不可能です。
それでは、関数オブジェクトを媒体として使用し、関数オブジェクトのプロトタイプ属性を使用してプロトタイプを転送し、new 演算子を使用して新しく作成されたオブジェクトにそれを渡すことができますか?
実際、次のようなコードでこの目標を達成できます。
function anyfunc(){}; //関数シェルを定義します。
anyfunc.prototype = person; //プロトタイプ オブジェクトを転送ステーション プロトタイプに配置します。
var BillGates = new anyfunc(); //新しいオブジェクトの組み込みプロトタイプは、私たちが期待するプロトタイプ オブジェクトになります
ただし、この anyfunc 関数は単なるシェルであり、このシェルを使用すると冗長になりますこれは、コンストラクターを直接使用してオブジェクトを作成するのと何ら変わりませんが、少し不快です。
しかし、これらのコードを一般的な関数として記述し、関数本体が関数内の関数になった場合、外側の関数がスコープから出た後、この内側の関数は自動的に終了するのではありませんか?さらに、プロトタイプ オブジェクトを一般関数のパラメータとして使用し、作成されたオブジェクトを一般関数に返すようにすることもできます。必要なのは次の形式です。
function New(aClass, aParams) //一般的に作成された関数
{
function new_() //一時的なトランジット関数を定義 Shell
{
aClass .Create.apply(this, aParams); //プロトタイプで定義されたコンストラクターを呼び出し、構築ロジックと構築パラメータを転送します
new_.prototype = aClass; //プロトタイプ オブジェクトの転送を準備します。 🎜> return new new_(); //最終的に作成されたオブジェクトを返します
};
var Person = //定義されたクラス
{
Create: function(name, age)
{
this.name = 名前;
this.age = 年齢;
},
SayHello: function()
{
alert("こんにちは、" this.name ) ;
},
HowOld: function()
{
alert(this.name " は " this.age " 歳です。");
}
}; 🎜 >var BillGates = New(person, ["Bill Gates", 53]); // 一般関数を呼び出してオブジェクトを作成し、配列の形式で構築パラメータを渡します
BillGates.SayHello(); 🎜>BillGates.HowOld() ;
alert(BillGates.constructor == Object); //出力: true
ここでの一般関数 New() は「文法的なネクター」です。この構文ネクターは、プロトタイプ オブジェクトを転送するだけでなく、コンストラクター ロジックと構築パラメーターも転送します。
興味深いのは、オブジェクトが作成されて New 関数スコープを出るたびに、一時的な new_function オブジェクトが自動的に解放されることです。 new_ のプロトタイプ属性が新しいプロトタイプ オブジェクトに設定されているため、元のプロトタイプ オブジェクトと new_ の間の参照チェーンが解け、一時関数とその元のプロトタイプ オブジェクトが正しくリサイクルされます。上記のコードの最後の文は、新しく作成されたオブジェクトのコンストラクター プロパティが Object 関数を返すことを証明しています。実際、新しく作成されたオブジェクト自体とそのプロトタイプにはコンストラクター属性がないため、返されるのは最上位のプロトタイプ オブジェクト、つまり Object のコンストラクターのみです。
New の構文ネクターを使用すると、クラスの定義は C# の静的オブジェクト言語形式に非常に似ています。このようなコードはなんと静かでエレガントでしょう。
もちろん、このコードは「文法ネクター」の概念を示しているだけです。また、クラス階層とその継承関係を簡潔でエレガントなコードで記述するためには、さらに多くの構文が必要です。それでは、より豊富な例を見てみましょう:
//構文 nectar:
var object = //最も基本的なメソッドの実装などに使用される、小文字のオブジェクトの基本クラスを定義します。
{
isA: function(aType) //クラスとオブジェクトとクラスの関係を判断するための基本的なメソッド
{
var self = this
while(self)
{
if ( self == aType)
return true;
self = self.Type>}
return false; //クラスと継承関係を宣言するために使用されるクラスを作成する関数
{
function class_() //クラスの一時関数シェルを作成します
{
this.Type = aBaseClass; //各クラスの Type 属性に同意し、その継承クラスを参照します。
for(var member in aClassDefine)
this[member] = aClassDefine[member] //クラスのすべての定義を現在の作成 Class
};
class_.prototype = aBaseClass;
return new class_()
}; // オブジェクトを作成する関数任意の Class オブジェクト作成用
{
function new_() // オブジェクトの一時関数シェルを作成します
{
this.Type = aClass; // それぞれの Type 属性にも同意します。これにより、オブジェクトが属するクラスにアクセスできます。
if (aClass.Create)
aClass.Create.apply(this, aParams); //すべてのクラスのコンストラクターが Create と呼ばれることに同意します。これは DELPHI
};
new_.prototype = aClass;
return new_();
}// 構文の適用効果:
var Person = Class(object, // オブジェクトの基本クラスから派生
{
Create: function(name, age)
{
this.name = name;
this.age = 年齢;
},
SayHello: function()
{
alert("こんにちは、" this.name "、" this.age " 歳です。"); >}
});
var Employee = Class(person, // Person クラスから派生したもので、一般的なオブジェクト言語と非常に似ていますか?
{
Create: function(name, age,給与)
{
person.Create.call(this, name, age) // 基本クラスのコンストラクターを呼び出します
this .給与 = 給与;
ShowMeTheMoney: function()
{
alert(this.name " $" this.salary); > var BillGates = New(人, ["ビル・ゲイツ", 53]);
var SteveJobs = New(従業員, ["スティーブ・ジョブズ", 53, 1234]);
BillGates.SayHello(); 🎜 >SteveJobs.SayHello();
SteveJobs.ShowMeTheMoney();
var LittleBill = New(BillGates.Type, ["Little Bill", 6]); 🎜>LittleBill .SayHello();
alert(BillGates.isA(人)); //true
alert(BillGates.isA(従業員)); //false
alert(SteveJobs.isA(人) )); //true
alert(Person.isA(Employee)); //false
alert(Employee.isA(Person)); //true
あまり「文法」は必要ありませんnectar」を少しだけ追加すると、コード全体の読みやすさと流暢さが向上し、コードがよりエレガントになります。これらの構文の蜜を使用すると、JavaScript は一般的なオブジェクト言語によく似たものになり、コードを書くのがずっと楽しくなります。
良いニュースは、これらの蜜を栄養とする JavaScript プログラムの効率が向上するということです。プロトタイプ オブジェクトには無駄なオブジェクト レベルのメンバーがなく、コンストラクターのプロパティ本体もないため、コンストラクターとの関与は少なくなりますが、メソッドの共有は維持されます。これにより、JavaScript がプロトタイプ チェーンをトレースし、プロパティやメソッドを検索する際の時間を大幅に節約できます。
この形式を「マナモデル」と呼びましょう!実際、この「マナ モデル」のプロトタイプの使用法は、プロトタイプの概念の本来の意味と一致しており、JavaScript プロトタイプの本当の意味です。
マイクロソフトで AJAX アーキテクチャを設計したエンジニアは、この蜜モデルを見たとき、AJAX 部門をもっと早くに米国から中国の観音寺に移転しなかったこと、観音菩薩の悟りを見逃したことを後悔したに違いありません。もちろん、コード例ではビル・ゲイツをオブジェクトとして扱うことしかできませんが、彼が神を捨てて仏陀に改宗するのは決して簡単ではありません。いつか、Microsoft の新しい AJAX クラス ライブラリでこの種のネクター モデルを目にすることができたら、それはまさに運命です。
プログラミングの楽しさ
今日、ソフトウェア業界の急速な発展に伴い、さまざまなプログラミング言語が際限なく登場し、新しい言語の誕生と古い言語の進化が私たちを驚かせているようです。 。オブジェクト指向プログラミングの傾向に適応するために、JavaScript 言語も完全にオブジェクト指向の方向で開発されており、新しい JavaScript 標準では多くの新しいオブジェクト指向要素が意味的に拡張されています。それどころか、多くの静的オブジェクト言語も JavaScript のシンプルさと優雅さの方向に向かって発展しています。たとえば、C# 言語の新しいバージョンには、JSON などの簡潔な表現や、その他の形式の JavaScript 機能が組み込まれています。
RIA (Strong Internet Application) の開発と普及により、AJAX テクノロジーは徐々に世の中から消えていき、最終的には JavaScript が消滅するか、他の形式の言語に進化することになるでしょう。しかし、プログラミング言語がどのように発展し、進化しても、プログラミングの世界は常に「データ」と「コード」の分かちがたい絡み合いの中で無限の活力を維持し続けます。これを見抜くことができれば、ソフトウェアの世界でさまざまな新しいことを簡単に学び、理解することができます。よく知られた手続き型プログラミングであっても、開発中の関数型プログラミングであっても、将来の量子もつれ状態の超並列プログラミングであっても、私たちはすべての複雑な問題を解決するのに十分な魔法の力を持っています。