如何在Javascript中创建静态变量?
当前回答
以下示例和解释来自Nicholas Zakas的《Web开发人员专业JavaScript第二版》一书。这是我一直在寻找的答案,所以我认为在这里添加它会很有帮助。
(function () {
var name = '';
Person = function (value) {
name = value;
};
Person.prototype.getName = function () {
return name;
};
Person.prototype.setName = function (value) {
name = value;
};
}());
var person1 = new Person('Nate');
console.log(person1.getName()); // Nate
person1.setName('James');
console.log(person1.getName()); // James
person1.name = 'Mark';
console.log(person1.name); // Mark
console.log(person1.getName()); // James
var person2 = new Person('Danielle');
console.log(person1.getName()); // Danielle
console.log(person2.getName()); // Danielle
本例中的Person构造函数可以访问私有变量名,getName()和setName()方法也是如此。使用此模式,name变量将变为静态,并将在所有实例中使用。这意味着在一个实例上调用setName()会影响所有其他实例。调用setName()或创建新的Person实例会将name变量设置为新值。这会导致所有实例返回相同的值。
其他回答
试试这个:
如果我们定义一个属性并重写其getter和setter以使用Function Object属性,那么理论上可以在javascript中使用一个静态变量
例如:
函数Animal(){if(isNaN(this.totalAnimalCount)){this.totalAnimalCount=0;}this.totalAnimationCount++;};Object.defineProperty(动画原型,“totalAnimalCount”{获取:函数(){return Animal['totalAnimalCount'];},集合:函数(val){动物['totalAnimalCount']=val;}});var cat=新动画();console.log(cat.totalAnimationCount)//将产生1var dog=新动画();console.log(cat.totalAnimationCount)//将产生2等。
您可以使用arguments.callee存储“静态”变量(这在匿名函数中也很有用):
function () {
arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
arguments.callee.myStaticVar++;
alert(arguments.callee.myStaticVar);
}
我有通用方法:
创建对象,如:stat_flags={};将其用于动态添加字段:flags.popup_save_inited=true;下次询问对象中是否需要标记并执行逻辑
例子:
class ACTGeneratedPages {
constructor(table_data, html_table_id) {
this.flags = {};//static flags for any processes
//any your code here
}
call_popup(post_id) {
let _this = this;
document.getElementById('act-popup-template').style.display = 'block';
if (!this.flags.popup_save_inited) {//second time listener will not be attached
document.querySelector('.act-modal-save').addEventListener('click', function (e) {
//saving data code here
return false;
});
}
this.flags.popup_save_inited = true;//set flag here
}
}
我经常使用静态函数变量,很遗憾JS没有内置的机制。我经常看到代码中的变量和函数是在外部范围内定义的,即使它们只是在一个函数内使用。这很难看,容易出错,而且只是自找麻烦。。。
我想出了以下方法:
if (typeof Function.prototype.statics === 'undefined') {
Function.prototype.statics = function(init) {
if (!this._statics) this._statics = init ? init() : {};
return this._statics;
}
}
这为所有函数添加了一个“statics”方法(是的,放松一下),当调用时,它将向函数对象添加一个空对象(_statics)并返回它。如果提供了init函数,_statics将设置为init()结果。
然后,您可以执行以下操作:
function f() {
const _s = f.statics(() => ({ v1=3, v2=somefunc() });
if (_s.v1==3) { ++_s.v1; _s.v2(_s.v1); }
}
与另一个正确答案IIFE相比,这有一个缺点,即在每个函数调用中添加一个赋值和一个if,并向函数添加一个“_statics”成员,但也有一些优点:参数位于顶部而不是内部函数中,在内部函数代码中使用“static”是显式的,带有“_s”前缀,总体上看和理解起来更简单。
我没有在任何答案中看到这个想法,所以只是将其添加到列表中。如果是重复的,请告诉我,我会删除它并对另一个进行投票。
我在我的网站上创建了一种超级全球化。由于每次页面加载时都会加载几个js文件,而其他几十个js文件只加载在一些页面上,所以我将所有“全局”函数都放在一个全局变量中。
在我第一个包含的“全局”文件的顶部是声明
var cgf = {}; // Custom global functions.
然后我删除了几个全局助手函数
cgf.formBehaviors = function()
{
// My form behaviors that get attached in every page load.
}
然后,如果我需要一个静态变量,我只需将其存储在范围之外,例如文档就绪或行为附件之外。(我使用jquery,但它应该在javascript中工作)
cgf.first = true;
$.on('click', '.my-button', function()
{
// Don't allow the user to press the submit twice.
if (cgf.first)
{
// first time behavior. such as submit
}
cgf.first = false;
}
这当然是一个全局的,而不是静态的,但由于它在每次加载页面时都会重新初始化,所以它可以达到相同的目的。