2

「[JavaScript関数]は、参照する可能性のある、囲んでいるスコープで定義されている変数を内部に格納します。」

その変数のセットが何であるかをどのように判断できますか?

たとえば、EffectiveJavaScriptのDavidHermanは、この関数(およびクロージャ)を提供します。

function sandwichMaker() {

    var magicIngredient = "peanut butter";

    function make(filling) {
        return magicIngredient + " and " + filling;
    }

    return make;
}

var f = sandwichMaker();

document.writeln("<p>" + f("jelly") + "</p>");
document.writeln("<p>" + f("bananas") + "</p>");
document.writeln("<p>" + f("marshmallows") + "</p>");

確かに、magicIngredientはmake()にアクセスできる変数ですが、他に何がありますか?SandwichMaker自体が関数内にある場合はどうなりますか?そして、グローバルがあります。現在のスコープ内で関連する値を探すときに、関数は何を見ていますか?

4

3 に答える 3

1

SandwichMaker自体が関数内にある場合はどうなりますか?そして、グローバルがあります。

はい、親関数のすべての変数にアクセスできます(シャドウされていない場合)。そして、最もスコープの高い関数は、グローバルスコープから継承します。

現在のスコープ内で関連する値を探すときに、関数は何を見ていますか?

デバッガーでそれを調べることができます。debugger;にステートメントを挿入しmake、それを実行して、devtoolsを調べます。次のようなものが表示されます。

Scope Chain
    0. make (currently executed):
        this: (+)Window
        arguments: (+)Arguments
        filling "jelly"
    1. sandwichMaker:
        arguments: (+)Arguments
        magicIngredient: "peanut butter"
        make: (+)Function
    Global
        AnonXMLHttpRequest: …
        ApplicationCache: …
        Array: …
        …

このすばらしい記事もご覧ください:http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-2-lexical-environments-ecmascript-implementation/

Chrome Devtoolsでのビューの例:

www.briangrinstead.comから)

于 2013-01-16T19:07:42.910 に答える
1

JavaScriptは関数スコープを使用します。これは非常に簡単に理解できます。関数で宣言されたものはすべて、その関数のスコープとそれより高いスコープを持っています。

クロージャは、特定のスコープ特定の時点(関数が作成されたとき)の2つが組み合わされていると考えることができます。

確かに、magicIngredientはmake()にアクセスできる変数ですが、他に何がありますか?

make作成時にスコープにアクセスできたもの。これには、関数内のすべての変数と、makeより高いスコープが含まれます。makeのスコープは閉じられていると言われます-作成された時点で存在していたスコープを超えて、常ににアクセスできるようにしmagicIngredientます。

SandwichMaker自体が関数内にある場合はどうなりますか?

次にmake、そのスコープ(作成時makeに存在していた)にもアクセスできます。

そして、グローバルがあります。現在のスコープ内で関連する値を探すときに、関数は何を見ていますか?

インタプリタは、現在実行中のスコープで参照されている変数を検索します。それらが見つからない場合は、次に高いスコープを調べます。変数が見つかるかスコープがなくなるまで、どんどん高く見え続けます(グローバルスコープが最も高く、windowブラウザで実行されているjavascriptのオブジェクトとも呼ばれます)。

関連する概念はシャドウイングです。2つの変数は親/子スコープで同じ名前を持つことができます。子は優先されるため、親を「シャドウイング」すると言われます。これは悪い習慣であることに注意してください。

クロージャとスコープがどのように機能するかを理解する最も簡単な方法は、このような単純なファクトリパターンを理解することです。内部関数が作成されて返されると、その時点でそのスコープにバインドされ、値が存在しなくなった後も適切な値を警告し続けます。

これがお役に立てば幸いです-1つの質問にたくさんの質問が詰め込まれています:)

于 2013-01-16T19:19:53.683 に答える
0

上記function sandwichMaker()で定義された変数があったとしましょう...

var something = 'something';
function sandwichMaker () {
...

AND内からsomethingアクセスできます。sandwichMaker()make()

外部変数には、関数内からアクセスできます。var something = 'something else'内に設定すると、関数自体の中make()に効果的に外側を隠すことになります。ただし、を設定するだけで、すべてのスコープで値が変更されます。その変数を再度宣言した場合にのみ、値が非表示になります。var somethingmake()something = 'something else'

于 2013-01-16T18:57:46.813 に答える