JavaScript中的静态变量
您可能利用JS函数也是对象这一事实 - 这意味着它们可以拥有属性。
例如,引用(现在已消失)文章JavaScript中的静态变量中给出的示例:
function countMyself() { // Check to see if the counter has been initialized if ( typeof countMyself.counter == 'undefined' ) { // It has not... perform the initialization countMyself.counter = 0; } // Do something stupid to indicate the value alert(++countMyself.counter); }
如果您调用该函数多次,则会看到计数器正在递增。
这可能比通过全局变量来污染全局命名空间的解决方案好得多。
这里是另一个基于闭包的可能解决方案:在JavaScript中使用静态变量的技巧:
var uniqueID = (function() { var id = 0; // This is the private persistent value // The outer function returns a nested function that has access // to the persistent value. It is this nested function we're storing // in the variable uniqueID above. return function() { return id++; }; // Return and increment })(); // Invoke the outer function after defining it.
这样可以得到相同类型的结果 - 但是这次递增的值是返回的,而不是显示的。
如果你来自于一门基于类、静态类型的面向对象语言(如Java、C++或者C#),我猜你正在尝试创建与"类型"关联的变量或方法,而不是与一个实例相关联。
通过使用"传统"的构造函数方法,也许可以帮助你理解JavaScript基本面向对象的概念:
function MyClass () { // constructor function var privateVariable = "foo"; // Private variable this.publicVariable = "bar"; // Public variable this.privilegedMethod = function () { // Public Method alert(privateVariable); }; } // Instance method will be available to all instances but only load once in memory MyClass.prototype.publicMethod = function () { alert(this.publicVariable); }; // Static variable shared by all instances MyClass.staticProperty = "baz"; var myInstance = new MyClass();
staticProperty
被定义在MyClass对象中(它是一个函数),并且与它所创建的实例没有任何关系,JavaScript将函数视为"一等对象"(first-class objects),因此作为一个对象,你可以为一个函数分配属性。
更新:ES6引入了通过class
关键字声明类的能力。这是对现有基于原型的继承的语法糖。
static
关键字允许你在一个类中轻松地定义静态属性或方法。
让我们看看如何使用ES6类实现上面的例子:
class MyClass { // class constructor, equivalent to // the function body of a constructor constructor() { const privateVariable = 'private value'; // Private variable at the constructor scope this.publicVariable = 'public value'; // Public property this.privilegedMethod = function() { // Public Method with access to the constructor scope variables console.log(privateVariable); }; } // Prototype methods: publicMethod() { console.log(this.publicVariable); } // Static properties shared by all instances static staticProperty = 'static value'; static staticMethod() { console.log(this.staticProperty); } } // We can add properties to the class prototype MyClass.prototype.additionalMethod = function() { console.log(this.publicVariable); }; var myInstance = new MyClass(); myInstance.publicMethod(); // "public value" myInstance.additionalMethod(); // "public value" myInstance.privilegedMethod(); // "private value" MyClass.staticMethod(); // "static value"