2

これは、javascript に関する技術的な質問です。javascript で、私のグループの 1 人のメンバーが、javascript オブジェクトの作成に関して奇妙なことを発見しました。何らかの理由で、オブジェクトのパラメーターは、オブジェクトのコンストラクターで作成されたメンバー変数に割り当てられずに、既にメンバーとして扱われています。以下のコードブロックに見られるように、パラメーターは変更可能です。

これは、私たちが行っているテストを示すコードです。

function NamedItem(name)
{
    name = 5;

    this.getName = function ()
    {
        return name;
    }
}


document.write(namedItem.getName() + "\n");  //5

これは合法ですか?それは危険ですか?

4

2 に答える 2

6

それはクロージャーと呼ばれます。
ネストされた関数は、親関数から変数にアクセスし、親関数の実行を超えて変数の有効期間を延長できます。

オブジェクトとは何の関係もありません。

于 2012-01-27T05:35:21.503 に答える
3

明確にするために、あなたがしていることには潜在的にばかげたことがいくつかあります。いくつかの原則を説明しましょう。

  1. などの関数の引数として変数を宣言する場合function(arg1, arg2)、変数自体 (変数の値ではなく) に関しては、関数の先頭で言うのと本質的に同じvar arg1; var arg2;です。は自動的に宣言されます。それらを再宣言しようとしても、渡された引数で動作します!

  2. 関数はオブジェクトです。オブジェクトはプロパティを持つことができます。したがって、関数は などのプロパティを持つことができますthis.getName = function()

  3. @SLaksが指摘したように、getNameメソッドのバージョンでクロージャーを作成しています。クロージャは、それが作成されたときに、その上にあるものの状態をキャプチャします。したがって、name作成時にスコープ内に変数が存在する場合、スコープ内のその名前の変数にアクセスできます。nameこれは JavaScript ではごく普通のことで、パブリック アクセサー関数 ( )を使用してプライベート プロパティ ( ) を作成できましたgetName。素晴らしい。

  4. このようなキーワードNamedItemでのインスタンスの作成を使用していると思います。. もう 1 つの方法 (そして、現在行っているよりも少ないメモリを使用する方法は、以下に示すように関数をプロトタイプに追加することです。プロトタイプ アプローチの欠点は、直接アクセスするのと同じくらい簡単にできることです。プライベート プロパティはありません。 JavaScript の伝統的な意味ですが、アンダースコア プレフィックスを使用して、プライベートであることを示し、それらを使用しない人もいます. このアプローチ (プロトタイプ) は、あなたのアプローチよりも少ないメモリを使用します.シングルプロトタイプ。newvar item = new NamedItem("javascripter")getName()NamedItem_nameNamedItem

代わりにプロトタイプを使用します。

function NamedItem(name) {
    this._name = name
}

NamedItem.prototype.getName = function() {
    return this._name
}

考えるきっかけになれば幸いです!

J

于 2012-01-27T05:51:51.197 に答える