2011-12-14 14 views
3

私はcodeacademyでJSを学ぼうとしていますが、このことは理解できません。誰かが回答を提供して、それがどうしてそういうのか説明することができますか?深く感謝します。スコープの仕組みを理解しようとしています

// This function tries to set foo to be the 
// value specified. 

function setFoo(val) { 
    // foo is declared in a function. It is not 
    // accessible outside of the function. 
    var foo = val; 
} 

setFoo(10); 

// Now that we are outside the function, foo is 
// not defined and the program will crash! Fix this 
// by moving the declaration of foo outside of the 
// function. Make sure that setFoo will still update 
// the value of foo. 
alert(foo); 
+0

正確には分かりませんが、あなたは関数*の外でfooの宣言を動かそうとしましたか? –

+1

このリンクを試してください:https://developer.mozilla.org/ja/JavaScript/Reference/Functions_and_function_scope –

答えて

2
// Create globale variable 
// (You should not use globale variables!) 
var foo; 

// set value 
function setFoo(val) { 
    foo = val; 
} 
setFoo(10); 

// show value 
alert(foo); 
+0

haha​​ha私たちは同じ回答を投稿しました。 = O –

+0

hehe、何か楽しい:) – PiTheNumber

2

ちょうどその時、それはグローバルになります任意の関数の外fooを宣言:

var foo = null; 

function setFoo(val) { 
    foo = val; 
} 

setFoo(10); 

alert(foo); 

はそれを試してみてください!

3

スコープは、コード内の特定の「レベル」に到達できる変数を意味する用語として使用できます。 JavaScriptでは、これらの「レベル」は関数によって定義されます。各関数は新しいレベルを導入します。例えば

、このサンプルコードを取る:

var a; 
// you can access a at this level 

function function1() { 
    var b; 
    // you can access a, b at this level 

    function function2() { 
    var c; 
    // you can access a, b, c at this level 
    } 
} 

は、だからあなたの場合には、あなたが好ましく、その上、関数の外var foo;を宣言する必要があります。次にsetFooの中にfoo = val;と設定できます。 fooは、レベルがsetFooで宣言したものを指します。

fooは、setFooalertの両方でアクセスできます。上記のサンプルコードと比較してください(function1setFooafooalertコールは最上位にあります。function2bおよびcは使用しません)。

1

オリジナルコード:

function setFoo(val) { 
    var foo = val; 
} 

setFoo(10); 

alert(foo); // Crash! 

クラッシュを修正するために彼らのアドバイス:

修正この機能

の外でのfooの宣言を移動することで、私はあなたを推測しています彼らは「機能の外」で意味することについて混乱している。

この編集したコードを試してみてください:関数内で定義されて

var foo = 5; // "var" declares the variable to be in this outer scope 

function setFoo(val) { 
    foo = val; // but we can still access it in this inner scope... 
} 

setFoo(10); 

alert(foo); // Displays a dialog box that says "10" 
0

変数はJavaScriptのみで

function setFoo(val) { 
    foo = val; 
} 
0

機能では、新しいスコープが関数のみ

2

自分で有効に作成されていますJavascriptで変数を宣言すると、宣言されている関数と同じ関数内にあるコードまたはその関数に固有の関数にのみ表示されます。 fooはもともとSetFoo関数で宣言されているため、SetFooの外部には何も表示されないので、fooが不安定なスコープに存在しないため、alertへの呼び出しは失敗します。

コメントが示唆しているように、fooの宣言を関数からグローバルスコープ(すべてを含むcatch-all関数と考えることができます)に移動すると、alertを呼び出すときにfooを使用できます。

var foo; 
function setFoo(val) { 
    foo = val; 
} 
setFoo(10); 
alert(foo); // No longer crashes 
2

Javascriptのすべての機能には独自の有効範囲があります。つまり、varキーワードで定義したすべての変数は、その関数内でのみ使用可能になります。これは、setFoo(10)を呼び出すと、変数fooを作成して5の値を与え、その後、スコープから外れてすぐに破棄されることを意味します。

この問題を解決する方法は複数あります。最初に、varキーワードを削除します。これはfooをグローバルスコープに置き換えます。つまり、どこでも使用できます。しかし、これは推奨されません。グローバルスコープをできるだけ整理しておきたいので、同じページに複数の人が提供するJavaScriptコードを他の人の変数に上書きすることはできません。それを行うための別の方法は、これを次のようになります。あなたはそれがどこでも利用できるようにしたいので、

この例では
function setFoo(val){ 
    var foo = val; 
    alertfoo = function(){ 
     alert(foo) 
    } 
} 

は、あなたがグローバルスコープに入れている唯一のものは、alertfoo機能です。 alertfoo関数はsetFoo関数の中で定義されています。これは、setfooが実行された後にfooが有効範囲外になったはずであるが、alertfooがアクセスできるのでメモリに保持されることを意味します。

これはいくつか素晴らしいトリックになります。たとえば、他の人のページに含まれるjavascriptライブラリを作成していて、グローバルスコープを汚染することなく変数を定義できるスコープを作成したいとします。これを行う最も一般的な方法は、自己実行機能を宣言することです。これは、このようになり、すぐに定義された後に実行される関数である。

(function(){ 
    //set variables you want to be global in your own code 
    var mainpage = document.getElementById('main'); 

    //define functions you want to make available to other people in a way that puts them in the global scope 
    setMainElement = function(newmain){mainpage = newmain;} 
})(); 

あなたは1つのオブジェクトのみがグローバルすることによって、これがさらに良く行い、そのオブジェクトのメソッドを通して、あなたのinterfaeを提供することができ、この方法ライブラリに含まれるすべての関数を含む名前空間を作成します。次の例では、これを行うためにオブジェクトリテラルを使用しています。 javascriptでは、キー/値のペアを中括弧で囲んでオブジェクトを作成することができます。キー/値のペアはオブジェクトのプロパティです。たとえば、

(function(){ 
    var privatevar = 10,otherprivate=20; 

    publicInterface = { 
     'addToPrivate': function(x){privatevar+=x;}, 
     'getPrivate': function(){return private} 
    }; 
})(); 
関連する問題