2016-08-25 12 views
-1

私は本You Don't Know JS: this & Object Prototypesに情報のこの作品に出会った:コードはfoo.count = 0を実行すると、...Javascript:関数のプロパティとは何ですか?その意味は何ですか?

さて、それはその後で述べます
function foo(num) { 
    console.log("foo: " + num); 
    this.count++; 
} 

foo.count = 0; 
for (var i=0; i<10; i++) { 
    if (i > 5) { 
     foo(i); 
    } 
} 

を実際にそれが追加していますプロパティオブジェクトcountを関数オブジェクトfooに割り当てます。

私は、関数のプロパティとその宣言方法を理解していません。

私は、関数もJSのオブジェクトであることを理解していますが、関数のプロパティの意義を理解していません。また、オブジェクトのプロパティには、このように定義されています。

var obj = {name: 'value'}; 

をしかし、どのようにfoo.count=0することができます - function foo()の範囲外 - foo()の下にプロパティを宣言します。このコードでは

+2

また、オブジェクトのプロパティを設定するために 'obj.name = 'value''と言うこともできます。オブジェクトが関数の場合はまったく同じです。 – Thilo

+0

@trincot:本は実際には全く同じ点を作っています。コードは 'console.log(foo.count);で終わります。 // 0 - WTF? '、それはOPによって複製されませんでした。 – Amadan

+0

私はその質問が 'foo.count'についてもっとあると思います。 – trincot

答えて

2

ルック:

var foo = { prop: 1 }; 
foo.count = 0; 
console.log(foo.count); // 0 

fooは、任意のオブジェクトにすることができます。それは{}として初期化する必要はありません。私は強調するために、変数に割り当てられた関数式としての機能を書いた

var foo = function (num) { 
    console.log("foo: " + num); 
}; 

foo.count = 0; 
console.log(foo.count); 

:それは、配列(例えば[1, 2, 3])、日付(例えばnew Date())、他のオブジェクトなども機能することができfooにオブジェクトが割り当てられていることを示します。しかし、それはまた、関数宣言の構文で動作します:

function foo(num) { 
    console.log("foo: " + num); 
} 

foo.count = 0; 
console.log(foo.count); 

限り、それはnot read-onlyあるとして、あるオブジェクトfooの種類をそれを問題ではありません、あなたはfoo.count = 0ようなものでプロパティを追加したり、上書きすることができます。

実際の例では、foo.countは関数が呼び出された回数をカウントする必要がありますが、機能しません。thisは関数を参照するのではなく、グローバルオブジェクトブラウザで実行している場合はwindow)。

はそれを修正するには、関数は次のようになります。

function foo(num) { 
    console.log("foo: " + num); 
    foo.count++; 
} 

...しかし、あなたは関数の名前を「ハードコーディング」する必要があるとして、それは、汎用的ではありません。

別の方法ではなく、(this answerから取られた)数値プロパティのcount方法で関数を作成するために、クロージャを使用している:

var foo = (function() { 
    var count = 0; 
    // Create the actual function 
    var f = function (num) { 
     console.log("foo: " + num); 
     count++; 
    }; 
    // ... and give it the count method 
    f.count = function() { 
     return count; 
    } 
    // Return that function (it will be assigned to foo) 
    return f; 
})(); // immediately execute the above code: it returns a function 

foo(2); // this increments count from 0 to 1. 

console.log(foo.count()); // 1 
+1

初心者にも* arguments * 'arguments.callee'は言及すべきではありません。それは非難され、忘れ去られた、それをそのままにしておいてください。 – Bergi

+1

@Bergieさん、ありがとうございました。非難されたステータスについてはっきりと言及しましたが、私はこれを廃止されていない別のソリューションに置き換えました。 – trincot

0

あなたは一種の質問を自分に答えています。

関数もオブジェクトです。あなたはfoo.count = 0が今ちょうどオブジェクトfooのプロパティを作成します呼び出すので

function foo(num) { 
    console.log("foo: " + num); 
    this.count++; 
} 

のような関数を定義する最初のステップで

。 Javascriptのオブジェクトの詳細についてはthisをお読みください。

あなたの例で知っておいていただきたいことの1つは、関数fooをどのように呼び出すかです。 thisは、どのように呼び出すかによって異なります。

お使いのブラウザのコンソールであなたの例をペーストして、呼び出しfoo.countはthisがグローバルコンテキストにバインドされますので、これは0です。

印刷されます。読んでhere

練習として、カウント機能を正しく動作させる方法を見つけることができます。

関連する問題