2017-10-19 5 views
0
function DoIHavePrototype() 
{ 
    var a = 10; 
} 

CheckIt = new DoIHavePrototype(); 

DoIHavePrototype.prototype.GetFnName = function() 
{ 
    return "DoIHavePrototype" 
} 

alert(CheckIt.GetFnName()) 

上記のコードでは、プロトタイプが、プロパティ/メソッドを関数に追加できるようにする関数の組み込みプロパティであることがわかりました。prototypeプロパティなしでコンストラクタ/関数にメソッドを追加することはできますか?

しかし、私は次のように上記のコードでは、プロトタイプのキーワードを削除する場合:メソッド アラートを呼び出し中に

DoIHavePrototype.GetFnName = function() 
    { 
     return "DoIHavePrototype" 
    } 

(私は関数定義のエラーを得ることはありませんが、代わりに、私はエラーを取得するCheckIt.GetFnName ()) "CheckIt.GetFnNameは関数ではありません"

JSインタープリタはこれを何と仮定していますか?

+3

クラスに関数を直接追加すると 'static method'が生成され、' Array.from'のように呼び出すことができます。したがって、あなたの場合、 'DoIHavePrototype.GetFnName();'のように(インスタンスではなく)クラスを使用して呼び出す必要があります。 – Krusader

+0

静的メソッドが作成されたことを知らせるためにcharm.tnxのように動作しました。 –

+0

私は実際の回答を作成しました。あなたの質問に答えた場合、それを答えと見なしてください。 – Krusader

答えて

1

MDNでこれを読むことができそうDoIHavePrototype.GetFnName();

好きなクラス(いないそのインスタンス)を使用して、それを呼び出す必要がありますそれをオブジェクトに導入する4つの方法があります。

最初の方法は、オブジェクトのプロトタイプに関数を割り当てることです、あなたの元のコードに何をやったかである:

Foo.prototype.myFunc = function() { .... } 

もう一つの方法は、コンストラクタ内thisにそれを割り当てることです。

function Foo() { 
    this.myFunc = function() { .... } 
} 

我々はまた、インスタンスに直接割り当てることができます。

var foo = new Foo(); 
var myFunc = function() { .... } 
foo.myFunc = myFunc 

最後に、我々は、インスタンスに関数をバインドすることができます。

var foo = new Foo(); 
var myFunc = function() { .... } 
var myFuncFoo = myFunc.bind(foo) 

最後のケースは、以来、少し特別ですインスタンスのプロパティではありませんが、呼び出しコンテキストがインスタンスに付加されているため、インスタンスメソッドのように動作する関数があります。

インスタンスメソッドを定義する最も一般的な方法は、プロトタイプへの割り当てです。コンストラクタのprototypeプロパティは、インスタンスが継承するものです。したがって、ここでは物を入れます。インスタンスはコンストラクタ関数ではなくprototypeプロパティから継承することに注意してください。コンストラクタのプロパティに何かを代入しても、それをインスタンスのプロパティとして利用することはできません。

thisへの割り当ては、バインドされたメソッドが必要な場合に使用されることがあります。例えば:私たちは別の関数(例えば、イベントハンドラ)の値としてinstance.boundMeth()を渡したい場合は

function Foo() { 
    this.boundMeth = this.meth.bind(this) 
    this.val = "foo" 
} 

Foo.prototype.meth = function() { 
    console.log(this.val) 
} 

これは便利です。JavaScriptでは、多くのオブジェクト指向言語とは異なり、これらの方法は、結合していないです:コンストラクタのプロトタイプに割り当てる場合

// Using Foo from the previous example 

function runner(fn) { 
    fn() 
} 
var obj = new Foo() 

runner(obj.meth) // Logs `undefined` 
runner(obj.boundMeth) // Logs `foo` 

、あなたは一括で割り当てることができます。

Foo.prototype = { 
    meth1: function() { .... }, 
    meth2: function() { .... }, 
} 

あなたはES6を使用する場合は、あなたもclassを使用することができますキーワード:

class Foo { 
    myFunc() { .... } 
} 

これはFoo.prototype.myFunc = function() { .... }と同じです。

+0

バインドメソッドを使用し、instance.boundMeth()を値として別の関数に渡すことについて述べた、バインドされていないバインドされたメソッドに関する最後のステートメントは理解できませんでした。 –

+0

明確にするために回答を編集します。 – hayavuk

+1

JavaScriptのトピックではなく「呼び出しコンテキスト」は、* thisの値が定義されている場所ではなく*どのように関数を呼び出すかに応じて変化することを意味します。ドット表記 'foo.bar()'を使って関数を呼び出すと、 'this'はドットの前にあるものです。ドットなしで呼び出すと、 'this'は(厳密モードでは)未定義であり、(厳密モードなしでは)グローバルオブジェクトです。 'bind()'関数は、あなたが関数をどのように呼び出すかにかかわらず、呼び出しコンテキスト*を変更/修正する能力を私たちに与えます。 (もっと詳しくはこちら:https://foxbunny.gitbooks.io/assimilate-js/content/this.html) – hayavuk

1

インスタンスメソッドとして使用したい場合に備えて、これを行うこともできます。あなたはまっすぐあなただけArray.fromで好きなクラスから呼び出すことができ、それがそのようにstatic method呼ば生成するクラスにあなたの機能を追加した場合

function DoIHavePrototype() 
{ 
    var a = 10; 

    this.GetFnName = function() { 
     return "DoIHavePrototype"; 
    } 
} 

CheckIt = new DoIHavePrototype(); 

alert(CheckIt.GetFnName()) 
1

。 は、だからあなたの場合には、あなたは、あなたがオブジェクトのメソッドをいくつかの機能を呼び出すことができるようにするために

関連する問題