CoffeeScript私有类实例变量

knp*_*wrs 18 javascript coffeescript

我有以下CoffeeScript代码:

class Person
  secret = 0
  constructor: (@name, @age, @alive) ->
  inc: -> secret++
Run Code Online (Sandbox Code Playgroud)

其中编译为以下JavaScript代码:

var Person;
Person = (function() {   
    var secret;
    secret = 0;

    function Person(name, age, alive) {
        this.name = name;
        this.age = age;
        this.alive = alive;
    }
    Person.prototype.inc = function() {
        return secret++;
    };
    return Person;
})();
Run Code Online (Sandbox Code Playgroud)

目前secret在所有实例之间共享Person.有没有办法secret在CoffeeScript中创建一个私有实例变量?

knp*_*wrs 18

我想出了一个解决方案.我不确定这是否是最好的解决方案,所以我仍然对其他人开放.

CoffeeScript的:

class Person
  constructor: (@name, @age, @alive) ->
    secret = 0
    @inc = -> secret++;
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

var Person;
Person = (function() {
    function Person(name, age, alive) {
        var secret;
        this.name = name;
        this.age = age;
        this.alive = alive;
        secret = 0;
        this.inc = function() {
            return secret++;
        };
    }
    return Person;
})();
Run Code Online (Sandbox Code Playgroud)


Nik*_*kov 16

CoffeeScript中没有私有成员的概念,因为JavaScript中没有.有一些局部变量,你可以在自己的解决方案中很好利用它们,但是当你的解决方案确实隐藏secretconstructor函数之外的任何变量时,它也会引入inc在类的每个实例化上重新声明方法的开销Person.

JavaScript社区中一个非常常见的错误是试图在其上设计其他语言的不存在的特征,这种模仿私人成员的尝试显然是一个例子.其中没有这样的概念,并且思考得更深,你会得出结论,JavaScript是一个非常宽松的动态环境,这将是不自然的.

因此,不要浪费你的应用程序的时间和性能来实现不存在的结构.只需专注于解决您的问题 - 而不是缺乏语言功能的问题.

现在问问自己:让所有成员公开会有什么伤害?

考虑到所有因素,最终的解决方案是:

class Person
  constructor: (@name, @age, @alive) ->
    @secret = 0
  inc: -> @secret++
Run Code Online (Sandbox Code Playgroud)

  • 它不模仿私人成员; 它只是更清楚地说明了如何使用该类.调用变量`secret`可能就足够了,但下划线前缀是更通用的解决方案.如果课程面向第三方,这尤其有用. (21认同)
  • 使用命名约定来表示"私有"变量是很常见的.与Python类似,这通常用`_var`表示,即在这种情况下是`_secret`. (4认同)