17

例:

function Foo() {
    this.bla = 1;
    var blabla = 10;
    blablabla = 100;
    this.getBlabla = function () { 
        return blabla; // exposes blabla outside
    }
}

foo = new Foo();

元の質問:

blaFoo のすべてのインスタンスに割り当てられることはわかっています。はどうなりblablaますか?

新しい質問:

私が今理解していること:

this.bla = 1;     // will become an attribute of every instance of FOO.
var blabla = 10;  // will become a local variable of Foo(**not** an attribute of every    instance of FOO), which could be accessed by any instance of FOO only if there's a method like "this.getBlabla".
blablabla = 100;  // will define a **new** (or change if exist) global(window) variable.

[質問:]正しく理解できましたか?

4

7 に答える 7

11

あなたが与える任意の internal-methods this-- つまり: Foo コンストラクター関数this.method = function () {}; 内にある間、すべてblahblahオブジェクトの各インスタンスに固有の への参照を持つことになりFooます。

function Wallet () {
    var balance = 0;
    this.checkBalance = function () { return balance; };
    this.depositAmount = function (amount) { balance += amount; };
}


var wallet = new Wallet();
wallet.checkBalance();   // 0
wallet.depositAmount(3);
wallet.checkBalance();   // 3

しかし、特権機能から誰かに返却しない限り、ウォレット外からのアクセスから完全に保護されています。

wallet.balance; // undefined;

(追加の興味深い点 -balanceが a string、 a number、または a のboolean場合、それを返したとしても、人々に編集権限を与えたり、永続的な表示アクセスを与えたりすることはありません。スカラー変数は値によって渡されるため、単にその時点で balance の値を渡します-- ただし、 balance がobject、 afunctionまたはであった場合array、彼らはあなたの内部の仕組みからがらくたを変更するための永続的なアクセス権を持っているでしょう)

注:これを機能させるには、コンストラクター内でメソッドを割り当てる必要がありますプロトタイプは内部変数にアクセスできません。後でメソッドを追加しても、内部変数へのアクセスは許可されません。

これは、各インスタンスが独自のメソッドのコピーを持ち、vars の独自のコピーを持っているため、各インスタンスがもう少し多くのメモリを消費することを意味します。しかし、あなたがしていることが個人的なデータを必要とする場合、これはそれを取得するための良い方法です.

于 2012-08-14T15:30:14.843 に答える
6

あなたの例blablaではローカル変数であるため、コンストラクター関数が終了すると消えます。

変数を使用するコンストラクター内で関数を宣言すると、変数はその関数のクロージャーの一部になり、関数が存在する限り (つまり、通常はオブジェクトが存在する限り) 存続します。

function Foo() {
  this.bla = 1;
  var blabla = 10;

  this.getBlabla = function() {
    alert(blabla); // still here
  }
}
于 2012-08-14T15:29:12.673 に答える
3

内のローカル(「プライベート」と考えてください) 変数になりますFoo()。外部からはアクセスできないということですFoo()

function Foo() {
  this.bla = 1; // this becomes an extension of Foo()
  var blabla = 10; // this becomes a "Local" (sort of like a 'private') variable
}

Foo メソッドを使用して (返すことで) 公開できます。

function Foo() {
    var blabla = 10; // local

    this.getBlabla = function () { 
        return blabla; // exposes blabla outside
    }
}

Foo() の外側:

var FooBar = new Foo();

var what_is_blabla = FooBar.getBlabla(); //what_is_blabla will be 10

jsFiddle デモンストレーション

于 2012-08-14T15:20:58.740 に答える
2

varコンストラクターとして使用される関数内で宣言された変数は、var任意の関数内で宣言された他のすべての変数と同様に、その関数の実行中にのみ表示されます (値がクロージャーを使用して閉じられていない限り)。

言い換えれば、blabla関数の外では効果的に見えません。

var foo = new Foo();
console.log(foo.bla);     // 1
console.log(foo.blabla);  // throws NameError

これらの変数を閉じる関数を定義することで、JavaScript が「プライベート」変数に最も近いものになります。

function Foo() {
    this.bla = 1;
    var private = 1;

    this.increment = function() {
        ++private;
    }

    this.getPrivateValue = function() {
        return private;
    }
}

foo = new Foo();
console.log(foo.bla);                // 1
foo.bla = 6;                         // legal
console.log(foo.bla);                // 6
console.log(foo.getPrivateValue());  // 1
// console.log(foo.private);         // would throw an error
foo.increment();                     // legal
console.log(foo.getPrivateValue());  // 2
// foo.getPrivateValue() = 5;        // syntax error. Still can't reassign to private no matter what you try!
于 2012-08-14T15:21:42.000 に答える
1

その変数はコンストラクターに対してローカルでありthis、クロージャーによってキャプチャされない限り、そのスコープ外 (それを介して、またはそれ以外の場合) にアクセスすることはできません。

于 2012-08-14T15:21:00.017 に答える
0

var キーワードを使用しない場合、「blabla」はグローバル変数になります。var なしで blabla を使用する場合、コードの他のポイントでもグローバルになり、誤って blabla の他のインスタンスを変更して、コードに意図しないバグを導入する可能性があります。「var」は変数を現在のスコープに配置するため、上記の場合、Foo のみがアクセスできます。

于 2012-08-14T15:21:54.137 に答える
-2

blablaの非公開メンバーと見なすことができますFoo

Douglas Crockford のこの記事を参照してください。

于 2012-08-14T15:21:50.193 に答える