1

JavaScriptで静的変数を調べていたところ、前に見たように、関数が定義され、関数定義のに関数プロトタイプが更新されていることに気付きました。

function MyClass () { // constructor function
  //function definition here
}

//now add a (static?) method *outside* the function definition
MyClass.prototype.publicMethod = function () {
  alert(this.publicVariable);
};

//add a static property *outside* the function definition
MyClass.staticProperty = "baz";

これが私の質問です-関数定義内で次のように定義してみませんか?

  function MyFunc(){
    MyFunc.staticVar = 1;
    //static method showing static var
    MyFunc.showVarStatic  = function(){
        alert(MyFunc.staticVar);
    }
    //instance method referring to static var
    this.showVarInstance = function(){
        alert(MyFunc.staticVar);
    }
    //instance method - doesn't change static var
    this.inc1 = function(){
        this.staticVar += 1;//no such property
    }
    //static method, changes var
    this.inc2 = function(){
        MyFunc.staticVar += 1;//increments static property
    }
  }

これは、IE8、FF、およびChromeで期待どおりに動作するようです。これは単なる個人的な好み/スタイルのものですか?私の機能全体がそれらの中括弧に含まれているので、私はそれが好きです。

[編集:さらに読んで実験した後、JavaScript関数がコンストラクターであり、たとえばC#クラスとどのように異なるかをよりよく理解しました-これを示すために使用したコードを次に示します]

//this is deceiving, notSoStaticVar won't exist until MyFunc1 has been run
//and then it will be reset whenever MyFunc1 (a constructor) is run
function MyFunc1(){
    MyFunc1.notSoStaticVar = "I belong to MyFunc1";
    this.instanceVar = "I belong to instances of MyFunc1";
}

//this code will be run inline one time, 
//so the static property of MyFunc2 will exist
//(I like how all the functionality is in one code block, but it's kind of messy)
MyFunc2 = (function(){
    var temp = function(){
        this.instanceVar = "I belong to an instance of MyFunc2";
    }
    temp.staticVar = "I belong to MyFunc2";
    return temp;
})();

//this seems to be equivalent to MyFunc2, but the code is cleaner
MyFunc3 = function(){
}
MyFunc3.prototype.instanceVar = "I belong to an instance of MyFunc3";
MyFunc3.staticVar = "I belong to MyFunc3";

//tests
console.log(MyFunc1.notSoStaticVar);//undefined!
var a = new MyFunc1();
console.log(MyFunc1.notSoStaticVar);//"I belong to MyFunc1"
console.log(a.instanceVar);//"I belong to instances of MyFunc1"
MyFunc1.notSoStaticVar = "I will be changed when another instance of MyFunc1 is created";
console.log(MyFunc1.notSoStaticVar);//"I will be changed when another instance of MyFunc1 is created"
var b = new MyFunc1();
console.log(MyFunc1.notSoStaticVar);//"I belong to MyFunc1" - was reset by constructor!

//now test MyFunc2
console.log(MyFunc2.staticVar);//"I belong to MyFunc2"
MyFunc2.staticVar = "I am not affected by the construction of new MyFunc2 objects";
var c = new MyFunc2();
console.log(c.instanceVar);//"I belong to an instance of MyFunc2"
console.log(MyFunc2.staticVar);//"I am not affected by the construction of new MyFunc2 objects"

//now test MyFunc3
console.log(MyFunc3.staticVar);//"I belong to MyFunc3"
MyFunc3.staticVar = "I am not affected by the construction of new MyFunc3 objects";
var d = new MyFunc3();
console.log(d.instanceVar);//"I belong to an instance of MyFunc3"
console.log(MyFunc3.staticVar);//"I am not affected by the construction of new MyFunc3 objects"

//interesting
console.log(c);//"temp" <-- not really intuitive!
console.log(d);//"MyFunc3" <-- makes sense
4

2 に答える 2

2

要するに:パフォーマンス。

関数内でそれらを定義すると、コンストラクターを呼び出すたびにそれらが再定義されます。

これは期待どおりに動作しますが、正当な理由がないため、オーバーヘッドにすぎません。

于 2012-06-13T00:22:38.987 に答える
1

これにより、すべてのオブジェクトインスタンスに固有の関数が追加されます。これは、多くの場合必要のない追加のメモリオーバーヘッドを消費します。

関数がローカル変数を参照する必要がある場合など、場合によっては便利ですが、そうでない場合は、プロトタイプに含める必要があります。

また、静的なものは常に上書きされます。

于 2012-06-13T00:23:02.873 に答える