如何在Typescript中声明函数内部的静态变量?

如何在Typescript中声明函数内部的静态变量?,typescript,Typescript,我知道我们可以在类中声明静态变量或函数 像这样 class SomeClass(){ static foo = 1; static fooBar(){ return ++SomeClass.foo; } } 有没有办法直接在函数内部声明一个静态局部变量 class SomeClass(){ fooBar(){ static foo = 1; return ++this.foo; } } 这是不可能的。您可以在类中声明静态,但不能在函数体中声明静态

我知道我们可以在类中声明静态变量或函数 像这样

class SomeClass(){
  static foo = 1;
  static fooBar(){ 
    return ++SomeClass.foo;
  }
}
有没有办法直接在函数内部声明一个静态局部变量

class SomeClass(){
  fooBar(){
    static foo = 1;
    return ++this.foo;
  }
}

这是不可能的。您可以在类中声明静态,但不能在函数体中声明静态

有没有办法直接在函数内部声明一个静态局部变量

class SomeClass(){
  static foo = 1;
  static fooBar(){ 
    return ++SomeClass.foo;
  }
}
它没有特殊的语法。但是如果您想要一个有状态函数,这里将介绍该模式:

例如:

class SomeClass {
    fooBar = (new class {
        foo = 1;
        inc = () => this.foo++;
    }).inc
}

let foo = new SomeClass();
console.log(foo.fooBar()); // 1
console.log(foo.fooBar()); // 2

我认为@basarat的回答有问题。添加以下内容:

let bar = new SomeClass();
console.log(bar.fooBar());
结果是
1
,因为
fooBar
不是一个方法,而是一个碰巧是函数的字段。因此,
SomeClass
的每个实例都有自己的
fooBar
闭包,并有自己独特的
foo

我认为,要像C++一样真实地模拟静态局部变量,答案应该是3,因为一个方法和一个代码> Foo<代码>是所有实例共享的。要在Typescript中执行此操作,您可以在类的其余部分之后定义

fooBar

SomeClass.prototype.fooBar = (function() {
    let foo = 1;
    function fooBar() {
        return foo++;
    }
    return fooBar;
})();
SomeClass {
...
    fooBar = (function () {
        let foo = 1;
        function fooBar(this: SomeClass) {
            return foo++;
        }
        return fooBar;
    })();
我还使用了不同的习惯用法来创建闭包,避免了引入新类,并且没有使用箭头符号。如果fooBar曾经需要访问实例的成员,那么现在就不会对这个所指的内容产生任何混淆


如果有必要,我想您还可以在类主体中包含
fooBar()
的伪定义,以满足类型检查;后续的外部定义应该简单地覆盖它。

改进@realh的答案,我能够在类内解决所有问题:

SomeClass.prototype.fooBar = (function() {
    let foo = 1;
    function fooBar() {
        return foo++;
    }
    return fooBar;
})();
SomeClass {
...
    fooBar = (function () {
        let foo = 1;
        function fooBar(this: SomeClass) {
            return foo++;
        }
        return fooBar;
    })();

this参数是访问类字段的关键部分。

Basarat,@Ryan Cavanaugh但为什么不可能呢?这是因为逻辑限制还是作者出于某种原因没有实现?@A.Singh因为TypeScript并不完美。但是它仍然非常棒:所有的语言特性都是从-100开始的。请看@realh下面的答案,了解上面的错误原因。+1-尽管讨论了静态特性,但它是一个有用的特性。实际上,这两种变量都应该存在:在类的所有实例的所有函数调用中都是静态的变量,在类的每个实例的所有函数调用中都是“有点静态”的变量。它不鼓励糟糕的设计吗?特别是对于鼠标操作,我需要在鼠标按下时设置某些标志,然后在鼠标移动时查看。当然,这些应该限定在方法的范围内,而不是组件的范围内。现在还不清楚如何降低方法级静态变量的级别。它不能在闭包上,因为方法闭包在类实例之间共享,也不能在类实例上,因为无法计算派生类(甚至基类)不知道的“安全”名称。如下面的@Trass3r所示,覆盖每个实例上的函数可能是实现此功能的解决方案。我对basarat答案的评论是,为什么每个实例静态也会有用,但不确定如何命名它们。