2016-05-24 6 views
1

console.log(myCounting.value);は、実際には7と表示されていました。これは、addメソッドが2回呼び出されたためです(コメント参照)。しかし、それは6を印刷します。それは範囲のためですか? myCounting.addで '呼び出し'関数を呼び出すと、そのスコープが異なるために値が変更されないことを意味しますか?私はスコープを学んでいるように誰かが説明することができます..ありがとうございます! 機能/オブジェクトの範囲

myCounting.add() 

this

はの呼び出し元のオブジェクトを参照:

をあなたの最初の例では:

function Counting(){ 
    this.value = 5; 
} 

Counting.prototype.add = function(){ 
    this.value++; 
} 

var myCounting = new Counting(); 
myCounting.add(); // invoked once 

function invoking(funcs){ 
    funcs(); 
} 

invoking(myCounting.add); //invoked twice 
console.log(myCounting.value); 
+2

「呼び出し(myCounting.add.bind(myCounting));」 – dandavis

答えて

1

残念ながら、JavaScriptでthisの値が異なった方法/関数が呼び出された場所に応じて評価しますadd関数(この場合、myCountingインスタンスです)。 2番目の例では

:それはトップレベルの範囲から呼び出されていますので、ここで

invoking(myCounting.add) 

は、addは(ブラウザ内から呼び出された場合)、トップレベルwindowオブジェクトにバインドされています。したがって、thisは実際にはグローバルウィンドウオブジェクトです。

結果は、ブラウザコンソールから直接this.value++を呼び出した場合と同じ結果になります。 this.valueundefinedなのでthis.value++の結果は(無意味)NaNです。

+0

* addは、グローバルに宣言された関数のように扱われ、トップレベルのウィンドウオブジェクトにバインドされています*それは* this *に設定されていますグローバルオブジェクトは呼び出しによって設定されていないため、オブジェクトが作成または呼び出し元となる場所は無関係です(矢印関数を除く)* this *は関数の呼び出し方法(または* bind *の使用方法)によって設定されます。 – RobG

+0

これは意味論的な違いですが、ここでの言葉は、関数が定義されている場所によって 'this'の値が異なるように見えることに同意できますが、これは一般的ではありません。 –

+0

2番目の最後の段落は依然として誤解を招く恐れがあります – RobG

2

スコープとはあまり関係ありません(スコープを作成する機能はおそらく?)。 thisの仕組みとは何かが関係しています。

thisの値はの機能はどのようにと呼ばれますか。関数を呼び出すことができる方法はいくつかあり、それぞれがthisの異なる値になる可能性があります。あなたの例では、myCounting.add()func()は異なる方法で関数を呼び出すため、thisの値が異なるため、this.value++が2つの異なるオブジェクトに適用されます。

詳細については、How does the “this” keyword work?およびおそらくHow to access the correct this/context inside a callback?を参照してください。

+0

tldr:scope!= 'this' – dandavis

+0

ありがとうございます。私が理解しているように、これは発信者を参照しています。次の例では、これはオブジェクトを参照していませんか?var name = "j"; するvar myObjectという= { \t名: "X"、 \tプロパティ:{ \t \t名: "Y"、 \t \t getFull:関数(){ \t \t \t戻りthis.name。 \t \t} \t} }; var fullname = myObject.property.getFull; fullname(); – learningcoding

+0

* "私が理解しているように、これは発信者を指しています。" *それは正しくありません(しかし、それはあなたが "発信者"という意味に依存すると思います)。ある関数だけが別の関数の呼び出し元になることができます。その意味では、「これ」は発信者を指すものではありません。 'this'が他の例のオブジェクトを参照していないのは、あなたが' fullname() 'として関数を呼び出すためです。関数がこのように呼び出されると、 'this'はグローバルオブジェクトを参照するか、strictモードで' undefined'となります。関数がどのように定義されたかは重要ではありません。関数はJavaScriptのファーストクラスの市民であり、自動的に束縛されません。 –

関連する問題