12

DouglasCrockfordの「JavascriptTheGoodParts 」を読み始めたところです。ここでは、彼が基本タイプの拡張について説明しています。

Function.prototype.addMethod=function(name,func) {
    this.prototype[name]=func; 
    return this; 
};

これを行った直後に、addMethodは、 StringNumberなどのすべての基本オブジェクトで使用できるようになります。

  1. Object.prototypeに追加していないのに、なぜこれが発生するのですか?

  2. Function.prototypeにメソッドを追加すると、すべての基本オブジェクトに反映されるのはなぜですか?

4

3 に答える 3

16

彼はおそらくこれを行った直後に、addMethodがString、Numberなどのすべての基本オブジェクト オブジェクトタイプで使用できるようになります。これは、Stringオブジェクトが関数であるためです(ただし、Stringによって作成されたオブジェクトは使用できません)。

例:与えられた

var s = '';

できるよ

String.addMethod(...);

だがしかし

s.addMethod(...);

JavaScript型システムの簡単な説明はここにあります:

JavaScriptには、クラスの通常の概念がありません。代わりに、呼び出されたときに関数の前に新しいキーワードを置くことで、関数をコンストラクターに変えることで、ある程度同じことを実現できます。

例:与えられた

function MyFunction(x) { this.myX = x; }

あなたがそれを次のように呼び出す場合

var myObj = new MyFunction(10);

myObjというオブジェクトが作成されます。このオブジェクトには、myXと呼ばれる単一のメンバー変数があります。関数MyFunctionは、オブジェクトのコンストラクターと見なされます(そして、「コンストラクター」プロパティに格納されます。

(ボーナス質問:新しいキーワードなしで上記の関数を呼び出すとどうなりますか。つまり、var x = MyFunction(10)答えはおそらく賢明な人を驚かせるでしょう。)

これで、任意の関数をコンストラクターに変換する方法を確認できました。組み込みオブジェクトはまったく同じです。文字列オブジェクトは関数Stringによって作成され、数値は関数Numberによって作成されます。

これらの組み込みオブジェクトが関数によって作成されるのと同じように、これらの各関数も「関数」関数によって作成されます(yikes!)。

次にプロトタイプに移ります。

上記の例では、どこかに書き込みます

MyFunction.prototype.someNewMethod = function() {}

MyFunctionコンストラクター/関数によって作成されたすべてのオブジェクトには、someNewMethodと呼ばれる追加のメンバー関数があるように見えます。プロトタイプを交換したり、プロトタイプのプロトタイプを交換したりするなど、プロトタイプを使用して他の多くのファンキーなことを行うことができますが、私はその専門家ではありません。

于 2009-09-03T11:26:54.537 に答える
1

オブジェクト指向のJavaScriptでは、関数はクラスとコンストラクターとして機能します。したがって、クラスの名前がMyObjectの場合、次のように実行できます。

// create a class/constructor
function MyObject() {
   // ...
}

// add a static method to the MyObject class
MyObject.someFunction = function() {
   // ...
}

// add an instance method to the MyObject Class
MyObject.prototype.someFunction = function() {
   // ...
}

この例では、addMethodがインスタンスメソッドとしてFunctionクラスに追加されました。これは、Functionのすべてのインスタンスで使用できることを意味します。MyObject関数/クラス/コンストラクターはFunctionのインスタンスであるため、addMethodを呼び出すことができます。これはほとんどすべてのオブジェクトタイプで機能しますが、IEやその他のブラウザのHTMLElementsでは機能しません。

于 2009-09-03T11:55:03.017 に答える
1
  1. JavaScriptの関数はオブジェクトです。すべてのオブジェクトには、Object.prototypeへの非表示のリンクがあります。したがって、最初の宣言の場合:

    > `Function.prototype.addMethod=function(name,func) {}
    

    Object.prototypeにリンクされているFunction.prototypeにリンクされている関数を宣言しました。

  2. 2番目の部分では、名前と値のペアをObject.prototypeに設定し、addメソッドをすべてのString、Numberオブジェクトに返します。これは、すべてプロトタイプで宣言されているためです。
于 2012-05-12T13:39:55.260 に答える