0

私が間違っていない場合、厳密モードでは、関数はグローバルオブジェクトにアクセスできません(「this」は関数に対して未定義です)。一方、クロージャが機能するには、内部関数がその親の「this」にアクセスする必要があります。JavaScriptは、strictモードでの内部関数の例外を作成しますか?

4

2 に答える 2

3

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、厳密モードではグローバル オブジェクトを指しますundefinedincrementしたがって、メソッドをに割り当てようとする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

それだけです。

于 2013-03-11T04:29:11.390 に答える
2

あなたの質問は、コンストラクターとインスタンス化されたオブジェクトを意味していたと思います。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 strictthisバインディングが設定されていない場合 (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どちらの影響も受けません。

于 2013-03-11T04:20:22.737 に答える