2012-06-13 44 views
1

我是看着Static variables in 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 
+1

从您在示例中编写的内容中,我想了解原型如何工作可能会有所帮助。您是否熟悉原型继承的工作方式,或者对快速浏览有帮助? –

+0

我已经阅读过有关原型,但从来没有真正与它们混淆过 - 并没有真正想过原型和静态变量(或方法)之间的关系。在进一步的思考和实验中,我可以看到如何使用原型并获得某种静态变量的惰性初始化,但该变量将始终由一个实例初始化......我从C#透视图,并意识到一些有趣的差异。我的例子中的 – Aerik

回答

1

因为这会为每个对象实例添加独特的功能。这会消耗额外的内存开销,而这通常不是必需的。

它在某些情况下可能很有用,例如函数应该引用局部变量,但如果情况并非如此,则应该放在原型上。

此外,静态的将不断被覆盖。

+0

,是不是MyFunc.somevar与MyFunc.prototype.somevar相同? – Aerik

+0

@Aerik:没有。功能是对象,所以你可以直接给它们添加属性,就像任何其他对象一样。所以你用'MyFunc.somevar'做什么是直接添加属性到函数。它对使用该函数创建的对象没有影响。但是添加像MyFunc.prototype.somevar这样的属性可以使'MyFunc'创建的所有对象都可以使用'somevar'属性。 – 2012-06-13 14:24:53

2

总之:表现。

在函数内部定义它们会在您每次调用构造函数时重新定义它们。

虽然这会像预期的那样行事,但这只是没有理由的开销。

相关问题