web-dev-qa-db-ja.com

グローバルに定義された変数が未定義なのはなぜですか?

こんにちは皆さん、私は単純な関数とグローバル変数を持っています。

文字列"global"ではなく、なぜmynameundefinedなのですか?

var myname = "global"; // global variable
function func() {
    alert(myname); // "undefined"
    var myname = "local";
    alert(myname); // "local"
}
func();

その関数のスコープ外で定義されている外部変数を参照することはできませんか?これでグローバル変数...

そして、グローバル変数からundefinedを取得しないようにこれを修正するにはどうすればよいですか?

18
J Rod

巻き上げと呼ばれるjsの「機能」につまずいた

var myname = "global"; // global variable
function func() {
    alert(myname); // "undefined"
    var myname = "local";
    alert(myname); // "local"
}
func();

このコードでfuncを定義すると、コンパイラーは関数本体を調べます。 mynameという変数を宣言していることがわかります。

Javascript Hoists変数と関数の宣言。関数の先頭に宣言を移動します。

巻き上げのため、コードは次のように書き直されます。

var myname = "global"; // global variable
function func() {
   var myname; //declare local variable and assign it undefined
   alert(myname); // "undefined"
   myname = "local"; // assign local var myname to "local"
   alert(myname); // "local"
}
func();

これはグローバル変数を「カバー」します。関数のスコープ内でグローバル変数にアクセスする場合は、thisキーワードを使用します。

var myname = "global"; // global variable
function func() {
    var myname = "local";
    alert(this.myname); // "global"
    alert(myname); // "local"
}
func();

thisキーワードは、関数の呼び出し方法に基づいてそのバインド先を変更するため、これはメソッドまたはコンストラクターではなく関数の呼び出しでのみ機能することに注意してください。

編集:完全を期すために

関数の種類に関係なく任意のコンテキストでグローバル変数にアクセスしたい場合は、慣例ではカバーできないグローバル変数を宣言します。

var global = this; // in global scope.
var myname = "global";
var obj = {f: function () {
    var myname = "local";
    console.log(global.myname);
}};
obj.f(); // "global"

これはメソッドの位置にあり、thisキーワードはobjを直接参照するため、mynameが定義されていないことに注意してください。

40
t3dodson

関数内では、var myname = "local"。メソッドの途中でそれを行っている場合でも、その変数は関数スコープを持っているため、その変数は関数全体に属し、その上のコードにも属します。

したがって、ローカル変数の値はその行の前では未定義であり、後に値がありますが、どちらもグローバル変数に触れていません。

3
Joe Enos

最初のアラートが未定義である理由は、関数でその下のローカル変数としてglobalを再宣言したためです。また、javascriptでは、関数の先頭からローカル変数と見なされます。

アラートのすぐ上に値を指定したため、その下のものが機能します。

0
Andrew