2009-09-03 19 views
12

Douglas Crockfordの "Javascript The Good parts"で基本的な型の拡張について説明しました。Javascript基本型の拡張(プロトタイプ継承)疑問

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

瞬間にこれをやった後、addMethod文字列のようなすべての基本的なオブジェクトのために利用可能になり、私の葉などが

を困惑[1]なぜこれが起こるん私はそれを追加していないときObject.prototype

Function.prototypeにメソッドを追加する理由[2]は、すべての基本オブジェクトに反映されますか?

私はjavascriptとprototypal継承にはかなり新しいです。だから私は本当に私の質問が愚かであるかどうかわからないのですか?彼はおそらくこれをやった後、瞬間を意味

+0

いいえ、それは愚かなJavaScriptのプロトタイプ継承の実装です。奇妙な関数をコンストラクタとして使用することで、プロトタイプの潜在的な利点は得られませんが、ほとんどのプログラマが理解できるクラスベースの継承とはまったく違っています。 JavaScriptのプロトタイプが何をしているのかを正確に理解することはうれしいですが、なぜそのモデルが理にかなっているかを明白にしているエピファニーは期待できません。それはしないので。 – bobince

答えて

16

は、addMethodは、すべての基本的な オブジェクトに対して利用可能になる オブジェクト型などの文字列、数値などのこのStringオブジェクトが関数である(ただし、文字列によって作成されたオブジェクトではないためであります)。 JavaScriptの型システムの

例えば、与えられた

var s = ''; 

あなた行うことができます

String.addMethod(...); 

なく

s.addMethod(...); 

簡単な説明がここに来る:

JavaScriptはありませんないクラスの通常の概念を持っています。その代わりに、新しいキーワードが呼び出されたときにその前に新しいキーワードを挿入することによって、関数をコンストラクタに変換することによって、いくらか同じことを達成できます。

例えば:あなたは

var myObj = new MyFunction(10); 

のようにそれを呼び出す場合

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

与えられ、それはこのmyobjと呼ばれるオブジェクトを作成します。このオブジェクトはmyXという単一のメンバ変数を持ちます。

(ボーナスの質問:上記の関数をnewキーワードなしで呼び出すとどうなりますか?つまり、var x = MyFunction(10)ですが、おそらくその答えはおそらく次のようになります。

組み込みオブジェクトはまったく同じもので、文字列オブジェクトは関数Stringによって作成され、数値は関数によって作成されます番号など

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

プロトタイプを作成します。上記の例では

、あなたはどこか

MyFunction.prototype.someNewMethod = function() {} 

を書く場合MyFunctionのコンストラクタ/関数によって作成されたすべてのオブジェクトはsomeNewMethodと呼ばれる余分なメンバ関数を持っているように見えます。プロトタイプを置き換えるか、プロトタイプのプロトタイプを置き換えるなど、プロトタイプを使って他の多くのファンキーなことをすることができますが、私はそれを熟知していません。

+0

'this.prototype [name]'で判断すると、あなたは正しいと思います。 –

+1

もう少し説明できますか?コンセプトを見つけるのは難しい。 –

+0

@erikkallen Stringオブジェクト型(またはその他の基本オブジェクト型)はどのように関数ですか?それはStringオブジェクトのように、Functionオブジェクトであるコンストラクタを持っていますか?これをもう少し説明してください! – sriramptr

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クラスのインスタンスメソッドとして追加されました。 MyObject関数/クラス/コンストラクタはFunctionのインスタンスなので、addMethodを呼び出すことができます。これはほとんどのオブジェクトタイプで動作しますが、IEや他のブラウザではHTMLElementsでは動作しません。

1
  1. JavaScriptの関数はオブジェクトです。すべてのオブジェクトには、Object.prototypeへの隠しリンク があります。したがって、最初の宣言のために:

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

    あなたは自分自身をのObject.prototypeにリンクされているFunction.prototypeにリンクされている機能を宣言しました。

  2. 名前の値のペアをObject.prototypeに設定し、すべてのString、Numberオブジェクトにaddメソッドを返します。これはプロトタイプで宣言されているためです。
関連する問題