3

私は Jquery についてかなり理解していますが、「生の」JavaScript を理解していないため、JavaScript の内部を掘り下げることにしました。
ここに私の問題があります:ドキュメントのロード時に関数が正常に実行され、アラートが表示されます: 「こんにちは、私の名前はジョンです」が、ボタンをクリックするとアラートが表示されます: 「こんにちは、私の名前は」です。私の質問は、なぜこれが起こっているのか、どうすれば解決できるのでしょうか?
変数を関数内に配置することで修正できることはわかっていますが、関数の外側で宣言された最初の変数(スクリプト型の直後の変数)を呼び出す方法はありますか?

ここでフィドル
私のコード:

<!DOCTYPE html>
<head>
<script type="text/javascript">

//If I try to call this variable WILL NOT WORK:(

var name ='John'; <--SO HOW CAN I CALL THIS VARIABLE TO MY CLICK FUNCTION?--> 

function displayName(name)
{
//If I put my variable like this WILL WORK fine...
//var name ='John';
alert('Hi I am '+name);

}

//This function works on document load
//displayName(name);
</script>
</head>
<body>

<!--This doesn't work well if variable is OUTSIDE my function:(-->
<button type="button" onclick="displayName(name)">Display Name</button>
</body>
</html>
4

3 に答える 3

15

あなたのコードは実際には問題ありません。global: に不幸な名前を選択しただけですname。他のもの ( などfoo) に変更すると、動作します: http://jsfiddle.net/6nuCx/1/

その理由はちょっと不明です。グローバル変数はwindowオブジェクトのプロパティになります。しかし、オブジェクトには、ウィンドウの名前であるwindowというプロパティが既にあります。あなたのコードがウィンドウの名前を上書きすることを期待していたので、あなたのコードが機能しなかったことに非常に驚いています。しかし、どうやらそうではありません。(これは、グローバル変数を避けることが最善である理由の良い例です。) とにかく、既存のプロパティと競合しない別の変数名を選択すると、それが整理されます。namename

しかし、コード内で明らかでない可能性のある何かを行ったので、もう少し深く掘り下げてみましょう (ここでは、foo混乱を避けるためにバージョンを使用しています)。

// Here, you're defining a global variable called `foo`
var foo ='John';

// Here you have a global function, `displayName`, which accepts an
// *argument* named `foo`
function displayName(foo)
{
    // Here, within the function, the symbol `foo` refers to the
    // *argument*, not to the global. The global is *hidden* by
    // the argument (this is called "shadowing" -- the local
    // "shadows" the global).
    alert('Hi I am '+foo);
}

そしてあなたのHTMLで:

<!-- Here, `foo` refers to the global variable -->
<button type="button" onclick="displayName(foo)">Display Name</button>

その引数の名前を変更すると、より明確になる可能性があります。

var foo ='John';

function displayName(f)
{
    alert('Hi I am '+f);
}

HTML は変更されていません。

<!-- Here, `foo` refers to the global variable -->
<button type="button" onclick="displayName(foo)">Display Name</button>

上記で、グローバル変数を避けるのが最善であり、あなたの問題がその理由の良い例であると述べました。では、どうすればよいのでしょうか。まあ、主に DOM0 ハンドラーを避けることによって (あなたの のようなonclick)。フィドルを再キャストする方法は次のとおりです。ライブコピー

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button id="theButton" type="button">Display Name</button>
<script type="text/javascript">
// Start a "scoping function"
(function() {
    // Everything within this function is local to the function,
    // not global
    var name = 'John';

    function displayName(n)
    {
        alert('Hi I am ' + n);
    }

    // Instead of the onclick= in the markup, hook up here in
    // the code
    document.getElementById("theButton").onclick = function() {
        displayName(name);
    };
})();
</script>
</body>
</html>

nameグローバルを作成したり操作したりしていないため、 を自由に使用できたことに注意してください。また、コードはボタンが既に存在することを前提としているため、ボタンのにコードを配置していることにも注意してください。

addEventListenerさらによいのは、 orを使用attachEventしてハンドラーを接続することです。

var btn = document.getElementById("theButton");
if (btn.addEventListener) {
    btn.addEventListener("click", handler, false);
}
else if (btn.attachEvent) {
    btn.attachEvent("onclick", handler);
}
else {
    // Punt!
    btn.onclick = handler;
}

function handler() {
    display(name);
}

ご覧のとおり、古いバージョンの IE (または「互換モード」の新しいバージョン) にはaddEventListener. これは jQuery のようなライブラリを使用する理由の 1 つですが、ライブラリを使用せずに理解を深めようとしているのは理解できますが、これには正当な理由があります。その上で最高!


そして最後に、あなたは尋ねました:

変数を関数内に配置することで修正できることはわかっていますが、関数の外側で宣言された最初の変数 (スクリプト型の直後の変数) を呼び出す方法はありますか?

上記の答えはどれもありません。:-) 答えは: はい、グローバルを隠していた引数を削除することで、直接参照できます:ライブの例

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var foo ='John';

// Note: No argument declared
function displayName()
{
    // Because the argument doesn't shadow it, we can refer
    // to foo, because foo is declared in an *enclosing
    // context*
    alert('Hi I am '+foo);
}
</script>
</head>
<body>
<!-- Note we don't pass any argument ------v -->
<button type="button" onclick="displayName()">Display Name</button>
</body>
</html>
于 2012-07-28T17:51:22.633 に答える
0

名前を使うのは悪い選択だと言いたかったのです。

http://jsfiddle.net/6nuCx/7/

于 2012-07-28T17:57:40.963 に答える
0

これを試して:

var name ='John'; 

function displayName()
{
alert('Hi I am '+name);

}

</script>
</head>
<body>

<button type="button" onclick="displayName()">Display Name</button>
</body>
</html>
于 2012-07-28T17:58:39.797 に答える