私が間違っていない場合、厳密モードでは、関数はグローバルオブジェクトにアクセスできません(「this」は関数に対して未定義です)。一方、クロージャが機能するには、内部関数がその親の「this」にアクセスする必要があります。JavaScriptは、strictモードでの内部関数の例外を作成しますか?
2 に答える
this
クロージャはポインタとは関係ありません。クロージャは、オブジェクト指向プログラミングではなく、関数型プログラミングの概念です。this
ポインターは、オブジェクト指向プログラミングの概念です。どちらも問題なく同時に独立して動作できます。
たとえば、厳密モードで次の関数を考えてみましょう。
function getCounter() {
"use strict";
var count = 0;
return function counter() {
return ++count;
};
}
ここで への呼び出しgetCounter
はクロージャーを返します。関数は valuecounter
を閉じcount
ます。次に、返されたカウンターを次のように使用できます。
var counter = getCounter();
counter(); // 1
counter(); // 2
counter(); // 3
クロージャーとネストされた関数を混同していると思います。次のスレッドを読んでください。クロージャーについて非常によく説明しています: JavaScript クロージャーと無名関数
厳密モードでは、this
ポインタはundefined
グローバル オブジェクトを指すときです。それ以外は普通に使えます。これにより、誤ってグローバル変数を作成することを防ぎます。ただし、支障はありません。
たとえば、次のコンストラクター関数を考えてみましょう。
function Counter() {
"use strict";
var count = 0;
this.increment = function () {
count++;
};
this.getCount = function () {
return count;
};
}
インスタンスを作成して、次のように使用できます。
var counter = new Counter;
counter.increment();
counter.getCount(); // 1
new
ただし、置くのを忘れた場合this
、厳密モードではグローバル オブジェクトを指しますundefined
。increment
したがって、メソッドをに割り当てようとするthis
と、エラーがスローされます。
元の質問に戻るとthis
、ネストされた関数でアクセスしたい場合は、ポインターの値をいつでも別の変数に格納できます。例えば:
function Counter() {
"use strict";
var that = this;
that.count = 0;
return function counter() {
return ++that.count;
};
}
これが本当にばかげた例であることはわかっていますが、私の主張を理解するために必要なすべての要素が含まれています。上記の関数を次のように使用できるようになりました。
var counter = new Counter;
counter(); // 1
counter(); // 2
counter(); // 3
それだけです。
あなたの質問は、コンストラクターとインスタンス化されたオブジェクトを意味していたと思います。use strict
プラグマは影響しません。式内のドットまたは角かっこ表記を使用して関数型のオブジェクトのプロパティにアクセスして呼び出すとThisBinding
、関数参照を取得したオブジェクトに が自動的に設定されます。
function Foo() {}
Foo.prototype.someMethod = function() {
console.log(this.blah);
};
var foo = new Foo();
foo.blah = 1;
//this:
foo.someMethod();
//implicitly does this:
foo.someMethod.call(foo);
TJ はおそらくMythical Methodsでこの動作をより簡単な方法で説明しています。
[...] オブジェクト プロパティ (
object.functionName()
または などobject['functionName']()
) から関数参照を取得する式を使用して関数を呼び出すと、オブジェクトは関数呼び出し内で自動的に "this" として設定されます。
use strict
this
バインディングが設定されていない場合 (null
または) にのみ違いが生じますがundefined
、ここではそうではありません。
すると、ご存じのとおり、this
関数コードを入力するときに参照が設定されていない場合、非厳密モードではグローバル オブジェクト (window
ブラウザー環境のオブジェクト) を参照し、厳密モードではundefined
. ES5.1 セクション 10.4.3を参照してください。
別の関数内の関数としてクロージャーを意味する場合は、古い字句スコープのトリックを使用してください。
function outerFunction() {
var _this = this;
function innerFunction() {
// _this references the outerFunction's this
}
}
この動作はuse strict
どちらの影響も受けません。