ホームページ >ウェブフロントエンド >jsチュートリアル >JScript_javascript スキルのプロトタイプ属性に関する研究JScript プロトタイプの研究
JScript のオブジェクトのプロトタイプ属性は、オブジェクト型のプロトタイプへの参照を返すために使用されることがわかっています。
prototype 属性を使用して、オブジェクトのクラスに基本的な機能セットを提供します。そして、オブジェクトの新しいインスタンスは、オブジェクトのプロトタイプに割り当てられた操作を「継承」します。しかし、このプロトタイプはどのように実装され、管理されるのでしょうか?
オブジェクトのプロトタイプ プロパティの説明については、JScript マニュアルに次のように記載されています。すべての JScript 内部オブジェクトには読み取り専用のプロトタイプ プロパティがあります。機能 (プロパティとメソッド) はそのプロトタイプに動的に追加できますが、オブジェクトに別のプロトタイプを与えることはできません。ただし、ユーザー定義オブジェクトを新しいプロトタイプに割り当てることはできます。
プロトタイプ属性の 3 つの古典的な使用例を見てみましょう。
1. スクリプト環境の組み込みオブジェクトにメソッドを追加します。
コードは次のとおりです。
Array.prototype.max = function() { var i, max = this[0]; for (i = 1; i < this.length; i++) { if (max < this[i]) max = this[i]; } return max; };
2. メソッドを追加します。ユーザー定義クラス:
コードは次のとおりです:
function TestObject(name) { this.m_Name = name; } TestObject.prototype.ShowName = function() { alert(this.m_Name); };
3. カスタム クラスのプロトタイプを更新します:
コードは次のとおりです:
function TestObjectA() { this.MethodA = function() { alert('TestObjectA.MethodA()'); } } function TestObjectB() { this.MethodB = function() { alert('TestObjectB.MethodB()'); } } TestObjectB.prototype = new TestObjectA();
3 番目のコードは見覚えがありますね。はい、前に紹介したプロトタイプの継承方法です~~ しかし、今日は「継承」について勉強するのではなく、この方法で継承を実装できる理由は、プロトタイプ属性の単なる副作用です。
プロトタイプにはデフォルトの属性、constructor もあります。これは、オブジェクトを作成する関数 (つまり、OOP のコンストラクター) を表すために使用されます。コンストラクター プロパティは、プロトタイプ プロパティを持つすべてのオブジェクトのメンバーです。これらには、Global オブジェクトと Math オブジェクトを除くすべての JScript 内部オブジェクトが含まれます。コンストラクター属性は、特定のオブジェクト インスタンスを構築する関数への参照を保持します。
JScript でのプロトタイプ属性の使用方法を理解したら、それを詳しく調べてみましょう。
前回の記事では、JScript でのプロトタイプ属性のさまざまな使用方法をリストしましたが、プロトタイプというものは、実際には JScript によって作成されたものではなく、デザイン パターンのプロトタイプ パターンの 1 つを派生した形で使用しています。ここで、プロトタイプ パターンについて簡単に説明してから、JScript のプロトタイプとは何ですか?
プロトタイプ パターンとは何ですか?
プロトタイプ インスタンスを使用して作成するオブジェクトの種類を指定し、このプロトタイプをコピーして新しいオブジェクトを作成します。
プロトタイプ インスタンスを使用して、作成するオブジェクトの種類を指定し、これらのプロトタイプをコピーして新しいオブジェクトを作成します。
プロトタイプ パターンを使用すると、作成方法の詳細を知らなくても、オブジェクトは別のカスタマイズ可能なオブジェクトを作成できます。その動作原理は、作成されるオブジェクトにプロトタイプ オブジェクトを渡すことによって、作成されるオブジェクトが実行されるというものです。プロトタイプ オブジェクトに自分自身をコピーするように要求することによって。
プロトタイプ パターンとは何かをさらに理解するには、「デザイン パターン - プロトタイプ」の記事を参照してください。Java を理解していなくても、そのコードを C# として扱うだけで問題ありません。
プロトタイプとは何か理解できましたか?とにかく、プロトタイプ パターンの実装はクローン操作に依存するということを覚えておいてください。もちろん、浅いコピーと深いコピーのどちらのクローンが必要かは、ニーズによって異なります。
JScript のプロトタイプについて話を続けましょう。なぜそれがプロトタイプ パターンのプロトタイプとは異なるのかというと、これは私が今言ったことではありません。この例を見ればわかるでしょう。混乱するかもしれません:
コードは次のとおりです:
<script language="javascript"> function RP() { RP.PropertyA = 1; RP.MethodA = function() { alert("RP.MethodA "); }; this.PropertyA = 100; this.MethodA = function() { alert("this.MethodA"); }; } RP.prototype.PropertyA = 10; RP.prototype.MethodA = function() { alert("RP.prototype.MethodA"); }; </script>
心配しないでください、まだ例を開始していません。クラスを提供しただけです。デモンストレーションに使用します。 RPとは何ですか? RPWT?もちろんそうではありません。RP は ResearchPrototype です。さて、早速、例と結果分析を見てみましょう。
コードは次のとおりです:
<script language="javascript"> rp = new RP(); alert(RP.PropertyA); RP.MethodA(); alert(rp.PropertyA); rp.MethodA(); </script>
実行結果が表示されます:
1
RP.MethodA
100
this .MethodA
この %$@#^$%&^...、心配しないで読み続けてください。
コードは次のとおりです:
<script language="javascript"> rp = new RP(); delete RP.PropertyA; alert(RP.PropertyA); delete RP.MethodA; RP.MethodA(); delete rp.PropertyA; alert(rp.PropertyA); delete rp.MethodA; rp.MethodA(); </script>
运行结果再次登场:
undefined
A Runtime Error has occurred.
Do you wish to Debug?
Line: 32
Error: Object doesn't support this property or method
10
RP.prototype.MethodA
好玩吧,看出来什么名堂了吗?这里的RP.PropertyA和RP.MethodA只是用来做参照的,可是怎么把this.PropertyA和this.MethodA都delete了,还能出来结果,而且还是prototype导入的属性和方法呢?
这就是JScript的prototype和prototype pattern中prototype最大的不同了,JScript中的这个所谓的prototype属性其实是个语言本身支持的特性,这里没有发生任何的copy,不管shallow还是deep的。对于JScript的解释引擎,它在处理"."或"[keyName]"引用的对象的属性和方法时,先在对象本身的实例(this)中查找,如果找到就返回或执行。如果没有查找到,就查找对象的prototype(this.constructor.prototype)里是否定义了被查找的对象和方法,如果找到就返回或执行,如果没有查找到,就返回undefined(对于属性)或runtime error(对于方法)。
正因为prototype导入类实例的属性或方法是动态查找的,所以我们才能对系统内部对象添加prototype属性和方法,比如给String对象添加trim方法:
代码如下:
<script lanuage="javascript"> String.prototype.trim() { return this.replace(/(^\s+)|(\s+$)/g, ""); } </scritp>
显然JScript中的这种用法也是prototype pattern中的prototype不能解释和支持的。
这下对于JScript OOP中原型继承法的理解因该没有任何的障碍了吧?同时也应该明白为什么原型继承法有那么大的天生缺陷了吧?当然如果有任何问题,欢迎继续讨论。
附演示示例源代码:
JScript Prototype Research <script language="javascript"> function RP() { RP.PropertyA = 1; RP.MethodA = function() { alert("RP.MethodA "); }; this.PropertyA = 100; this.MethodA = function() { alert("this.MethodA"); }; } RP.prototype.PropertyA = 10; RP.prototype.MethodA = function() { alert("RP.prototype.MethodA"); }; </script> <script language="javascript"> rp = new RP(); delete RP.PropertyA; alert(RP.PropertyA); delete RP.MethodA; RP.MethodA(); delete rp.PropertyA; alert(rp.PropertyA); delete rp.MethodA; rp.MethodA(); </script>