Javascript中静态值的闭包

Javascript中静态值的闭包,javascript,closures,Javascript,Closures,我有个问题。我们都知道Javascript中闭包的威力,我想使用这种威力。假设我有一个名为“BRB”的对象。我想知道的是,每当用户第一次调用getBrowser()方法时,它都会找到浏览器的版本/名称,然后返回它,并将其作为静态存储在自身内部。当第二次调用getBrowser()时,它应该返回相同的值,而不进行计算,因为它已经静态存储在某个地方。这可以通过许多不同的方式来完成,我们可以只在对象中存储一个属性,在第一次调用中,我们可以为它设置一些值,然后使用它,我们可以在以如下语法创建对象时直接运

我有个问题。我们都知道Javascript中闭包的威力,我想使用这种威力。假设我有一个名为“BRB”的对象。我想知道的是,每当用户第一次调用getBrowser()方法时,它都会找到浏览器的版本/名称,然后返回它,并将其作为静态存储在自身内部。当第二次调用getBrowser()时,它应该返回相同的值,而不进行计算,因为它已经静态存储在某个地方。这可以通过许多不同的方式来完成,我们可以只在对象中存储一个属性,在第一次调用中,我们可以为它设置一些值,然后使用它,我们可以在以如下语法创建对象时直接运行getBrowser方法

(function()(
...
))()
然而,这不是我想要的。我只希望getBrowser()方法只计算一次值并一直使用它,我不想将值存储在对象的其他位置,我不想在创建对象时立即运行此方法,我只允许使用且仅允许使用此方法,所有操作都必须在此方法中进行。我在这里举了一个例子,正如您所看到的,它总是打印出“0”,但我想要的是它为每个console.log请求打印0,1,2,3。我希望我说清楚了。谢谢

(
function(window){

    if(window.BRB) return;

    var BRB = function(){}
    BRB.prototype.getBrowser = function(){
        var browser = null;
        return function(){
            if(browser === null){
                browser = 0;
            }
            return browser++;
        }
    }

    window.BRB = new BRB();
})(window);

console.log(BRB.getBrowser()());
console.log(BRB.getBrowser()());
console.log(BRB.getBrowser()());
console.log(BRB.getBrowser()());
应在其他位置定义浏览器变量:

(
function(window){

    if(window.BRB) return;

    var browser = null;
    var BRB = function(){}
    BRB.prototype.getBrowser = function(){
        if(browser === null){
            browser = 0;
        }
        return browser++;
    }

    window.BRB = new BRB();
})(window);

console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
JSFIDLE

如果您能够将对象而不是函数指定给getBrowser:

(
function(window){

    if(window.BRB) return;

    var BRB = function(){}
    BRB.prototype.getBrowser = {
        browser: null,
        get: function() {
            if(this.browser === null){
                this.browser = 0;
            }
            return this.browser++;
        }
    }

    window.BRB = new BRB();
})(window);

console.log(BRB.getBrowser.get());
console.log(BRB.getBrowser.get());
console.log(BRB.getBrowser.get());
console.log(BRB.getBrowser.get());
应在其他位置定义浏览器变量:

(
function(window){

    if(window.BRB) return;

    var browser = null;
    var BRB = function(){}
    BRB.prototype.getBrowser = function(){
        if(browser === null){
            browser = 0;
        }
        return browser++;
    }

    window.BRB = new BRB();
})(window);

console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
JSFIDLE

如果您能够将对象而不是函数指定给getBrowser:

(
function(window){

    if(window.BRB) return;

    var BRB = function(){}
    BRB.prototype.getBrowser = {
        browser: null,
        get: function() {
            if(this.browser === null){
                this.browser = 0;
            }
            return this.browser++;
        }
    }

    window.BRB = new BRB();
})(window);

console.log(BRB.getBrowser.get());
console.log(BRB.getBrowser.get());
console.log(BRB.getBrowser.get());
console.log(BRB.getBrowser.get());

您可能希望
getBrowser
方法成为结果的IIFE闭包:

BRB.prototype.getBrowser = (function(){
    var browser = null;
    return function(){
        if(browser === null){
            browser = 0;
        }
        return browser++;
    }
})();
这样,
浏览器
变量就不会在每次函数调用时重新初始化

更新
对于浏览器值,可以使用属性而不是闭包中的变量范围:

BRB.prototype.getBrowser = function() {
    if(!this.browser){
        this.browser = 0;
    }
    return this.browser++;
}

您可能希望
getBrowser
方法成为结果的IIFE闭包:

BRB.prototype.getBrowser = (function(){
    var browser = null;
    return function(){
        if(browser === null){
            browser = 0;
        }
        return browser++;
    }
})();
这样,
浏览器
变量就不会在每次函数调用时重新初始化

更新
对于浏览器值,可以使用属性而不是闭包中的变量范围:

BRB.prototype.getBrowser = function() {
    if(!this.browser){
        this.browser = 0;
    }
    return this.browser++;
}

你的要求有点奇怪。这就是你要找的吗?它通过在getBrowser函数本身上创建属性来工作:

(function(window){

    if(window.BRB) return;

    var BRB = function(){}
    BRB.prototype.getBrowser = function(){
        if(typeof this.getBrowser.browser == "undefined"){
            return this.getBrowser.browser = 0;
        } else {
            return ++this.getBrowser.browser;
        }
    }

    window.BRB = new BRB();
})(window);

console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
console.log(BRB.getBrowser());

你的要求有点奇怪。这就是你要找的吗?它通过在getBrowser函数本身上创建属性来工作:

(function(window){

    if(window.BRB) return;

    var BRB = function(){}
    BRB.prototype.getBrowser = function(){
        if(typeof this.getBrowser.browser == "undefined"){
            return this.getBrowser.browser = 0;
        } else {
            return ++this.getBrowser.browser;
        }
    }

    window.BRB = new BRB();
})(window);

console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
console.log(BRB.getBrowser());
console.log(BRB.getBrowser());


同样没有充分的理由让
getBrowser
每次都返回一个新函数……正如我在问题中提到的,这是不允许的,我不能使用这种方式,因为它可以防止解耦。如果我想在其他地方使用此方法,我还必须将对象属性移动到另一个我不想要的对象中。唯一允许我们编辑的地方是getBrowser方法,除此之外什么都没有。显然,它不必返回函数。这只是一个伪代码,正如我提到的,这可以通过很多方式实现,我只是在试验,我复制并粘贴了代码。你使用一个变量,它存在于你每次创建的范围内。如果不将browser的值放置在作用域之外,则无法保持该值。我搜索的方式是,如何创建一个仅在getBrowser调用中可用的作用域,但仅在该方法中可用,且仅在其他方法中可用,如果这是不可能的,这也是一个答案:)我实际上正在搜索神奇的答案。
getBrowser
也没有很好的理由每次都返回一个新函数……正如我在问题中提到的,这是不允许的,我不能使用这种方式,因为它可以防止解耦。如果我想在其他地方使用此方法,我还必须将对象属性移动到另一个我不想要的对象中。唯一允许我们编辑的地方是getBrowser方法,除此之外什么都没有。显然,它不必返回函数。这只是一个伪代码,正如我提到的,这可以通过很多方式实现,我只是在试验,我复制并粘贴了代码。你使用一个变量,它存在于你每次创建的范围内。如果不将browser的值放置在作用域之外,则无法保持该值。我搜索的方式是,如何创建一个仅在getBrowser调用中可用的作用域,但仅在该方法中可用,且仅在其他方法中可用,如果这不可能,这也是一个答案:)我正在搜索神奇的答案。这将在创建对象时直接执行,正如问题中提到的,我不想这样做。如果我有100个这样的方法,它们都将在创建对象时执行,但我不需要在一开始就执行它们。这将在创建对象时直接执行,正如前面提到的,我不想这样做。如果我有100个这样的方法,它们都将在创建对象时执行,但我不需要一开始就执行它们。我不确定我是否理解,你是否可以在getBrowser上创建静态属性?我不确定我是否理解,你是否可以在getBrowser上创建静态属性,是否?这在prototype中创建了另一个对象属性,我不需要它,基本上与前面的注释相似,但实际上是一个很好的属性。它没有在prototype中创建另一个属性,而是在BRB.prototype.getBrowser上创建了一个属性。当我再次思考这个答案时,我认为它符合我的需要,确实非常好。非常感谢你!只有一件事:如果您试图从BRB外部使用它,那么这将失败,因此
var gb=BRB.getBrowser;gb()
将抛出错误。这将在prototype中创建另一个对象属性,我不需要它,它基本上与以前的注释相似,但实际上是一个很好的属性。它不会在prototype中创建另一个属性,而是在BRB.prototype.getBrowser上创建一个属性。当我再次思考这个答案时,我认为它符合我的需要,确实非常好。非常感谢你!只有一件事:这将失败