0

JavaScript の関数にはグローバル スコープとローカル スコープがありますか?以下のコードを参照してください

function doSomething()
{
    function foo()
{
    alert(this);
}

foo();
}
foo(); 

ここで関数foo()は実行されません。ただし、関数内の「this」キーワードは、関数が実行された場合、グローバルウィンドウオブジェクトを指します。doSomething()つまり、関数foo()がグローバルスコープで実行されていることを意味します。グローバルスコープで実行されているため、最初に実行せずにネストされた関数を直接実行できないのはなぜですかdoSomething().

4

2 に答える 2

1

スコープとコンテキストを混乱させています。最初の関数は特定の関数に対して固定され(関数によって返され、外部スコープに効果的に注入されない限り)、2番目の関数(特に、thisこの関数の内部を参照するものを定義します)は、呼び出されたときに関数に与えられます-callそして実際にはとで変更することができますapply

このことを考慮:

var someObj = function() {
    var internalObj = {
        nam: 'internal',
        doSomething: function() {
            console.log('Called from ' + this.name);
        }
    }
    internalObj.doSomething('Internal');      // 1
    var someFunc = internalObj.doSomething;
    someFunc();                               // 2
    return {
        nam: 'external',
        doSomething: internalObj.doSomething
    }        
}
var x = new someObj();
x.doSomething();                              // 3
setTimeout(x.doSomething, 1000);              // 4
setTimeout(x.doSomething.bind({nam:'a new one'}), 2000); // 5

JSFiddle

この例では、メソッド'doSomething'をinternalObj変数のプロパティとして定義します。これは、このコンストラクター関数のローカルです。の外部でアクセスしようとするとsomeObj、ReferenceErrorが発生します。

thisメソッドがコンストラクター関数自体(1)で呼び出されると、メソッドのコンテキストオブジェクト( )が参照するように、「内部から呼び出された」ログが記録されますinternalObj

このメソッド(その参照)を別のローカル変数に割り当て、そこから呼び出すと(2)、代わりに「undefined」がログに記録されます。スコープは明らかにここでは変更されていませんが、コンテキスト変数は変更されています。現在、グローバルオブジェクトを参照しています。

次に、コンストラクターの結果としてこのメ​​ソッドを返します。そして、物事ははるかに興味深いものになり始めます。関数が外部スコープで使用できるようになりました。ただし、(3)と(4)の呼び出しの結果の違いに注意してください。前者はexternal(ここでのコンテキストオブジェクトはコンストラクターによって作成されたものであるため)私たちに与えますが、後者は再び私たちを返しundefinedますが構文は同じです。)これは、タイムアウトに送信された関数とイベントハンドラーがコンテキストを「失う」ために発生します。つまりFunction.prototype.bind、(5)のようにメソッドで修正しない限り、コンテキストが失われます。

于 2012-12-22T08:58:07.110 に答える
0

JavaScript には関数レベルのスコープがあります。

関数宣言は、最も近い包含関数に自動的にスコープされます。

関数式は値 (つまり関数) を返すだけなので、任意の方法でスコープを設定できます。

これは、関数 foo() がグローバルスコープで実行されていることを意味します

スコープとコンテキストを混同しています。

スコープは、変数が宣言されている場所によって決定されます (varまたは「関数宣言のスコープ」などの特別なルールを使用)。変数が見える場所に影響します。

コンテキストは、関数の呼び出し方法によって決まります。の値が何であるかに影響しますthis

2つは接続されていません。

于 2012-12-22T08:58:03.990 に答える