Подтвердить что ты не робот

Переменные экземпляра частного класса CoffeeScript

У меня есть следующий код CoffeeScript:

class Person
  secret = 0
  constructor: (@name, @age, @alive) ->
  inc: -> secret++

Что скомпилируется с помощью следующего кода 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;
})();

В настоящее время secret разделяется между всеми экземплярами Person. Есть ли способ сделать secret переменную частного экземпляра в CoffeeScript?

4b9b3361

Ответ 1

В CoffeeScript нет концепции частных членов, поскольку в JavaScript нет. Существуют локальные переменные, которые вы используете хорошо в своем собственном решении, но в то время как ваше решение скрывает переменную secret от чего-либо вне функции constructor он также вводит накладные расходы на повторное использование метода inc при каждом экземпляре класса Person.

Ошибка, распространенная в сообществе JavaScript, пытается спроецировать на нее несуществующие функции других языков, что, очевидно, является попыткой подделать закрытых членов. Там нет такой концепции и глубже, вы поймете, что это будет просто неестественно для чрезвычайно рыхлой динамической среды, в которой работает JavaScript.

Поэтому не тратьте время и эффективность своего приложения на реализацию несуществующих конструкций. Просто сосредоточьтесь на решении своей проблемы, а не на проблемах отсутствия языковых функций.

Теперь спросите себя: что так обидно в том, что все члены общественности открыты?

Принимая во внимание все сказанное, окончательное решение будет:

class Person
  constructor: (@name, @age, @alive) ->
    @secret = 0
  inc: -> @secret++

Ответ 2

Я понял решение. Я не уверен, что это лучшее решение, поэтому я все еще открыт для других.

CoffeeScript:

class Person
  constructor: (@name, @age, @alive) ->
    secret = 0
    @inc = -> secret++;

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;
})();

Ответ 3

Пока он не будет их действительно скрывать, соглашение состоит в том, чтобы префикс "private" элементов с подчеркиванием. Идея здесь состоит в том, что люди, потребляющие это, должны предполагать, что такие члены являются деталями реализации и не рекомендуется использовать их.

Ответ 4

Обратитесь к этой теме, вы можете заставить ее работать только через закрытую функцию getter

Ответ 5

Вот трюк, который большую часть времени будет выполнять требование:

msg = "Result-----------\n"

class Dog

  #public variable
  dogName: null

  #private variables
  _private = []

  constructor: (@dogName, surname) ->
    _private[@dogName] = {surname: surname}

  #public method (note the => instead of ->)
  walk: =>
    msg += "#{@dogName} is walking\n"
    sayHello(@dogName, _private[@dogName].surname)

  #private method
  sayHello = (dog, surname) ->
    msg += "Hi! says #{dog}. Call me #{surname}\n"

window.ralph = new Dog("Ralph", "Ralphie")
window.peter = new Dog("Peter", "Pitty")
window.rex = new Dog("Rex", "Roxie")
rex.walk()
peter.walk()
ralph.walk()

alert msg

но вы должны иметь в виду, что: _private растет с каждым новым экземпляром (это общий массив), а ваш ключ (в данном случае @dogName) должен быть уникальным экземпляром экземпляра.

Попробуйте

Ответ 6

Фактически вы скрываете детали реализации, объявляя участника приватным. Используя наследование, вы можете скрыть детали реализации, объявив "абстрактный" класс (который, как я знаю, на самом деле не существует в CoffeeScript, и расширяет его своей собственной реализацией). Например:

  class bottle
        drink: ->
        empty: ->

  class bottle_impl extends bottle
        drink: -> 
             if count > 0
                 alert "drinking for the " + _count + " time."
       empty: -> @_count = 0
       _count: 4

теперь каждая функция, возвращающая бутылку, должна фактически вернуть файл__диски (в то время как скрывает этот факт от пользователя в комментариях). К сожалению, при расширении бутылки вы не будете расширять бутылку_impl, которая, вероятно, не то, что вы хотите.

Ответ 7

hmmmmmmmm не совсем верно. если вы хотите частных членов, вы не можете получить частных членов, но если вы действительно этого хотите, вы можете иметь его

class person 
  constructor:->
    name='my secret name'
    @getName=->
      name
    null


boy= new person()


alert boy.name  #it now private spits out undefined
alert boy.getName()

они должны находиться в области построения, чтобы это работало. это как можно ближе к частным, так как вы когда-либо получите.

Проблемы с частными пользователями замедляют работу приложения. Он должен запускаться каждый раз, когда он создан, и он не может просто получить его от прототипа. Получайте удовольствие

Ответ 8

Вы можете сделать что-то вроде этого...

class person
  secret = 
    name : "my secret name"
  constructor:->
    x = 123
  getName: ->
    secret.name

user = new person()

console.log user.name # undefined
console.log user.getName() # "my secret name"

На самом деле очень важно, что вам придется использовать переменную secret или _ или что бы вы ни выбрали для ссылки на частные переменные.

Ответ 9

Хотя Javascript не имеет концепции видимости, вы можете использовать области действия для имитации этого.

class Test
  privateVariable = null

  privateFunction = (obj)->
    privateVariable = obj
  constructor: (a) ->
    privateVariable = a

  publicFunction: ->
    return privateVariable

  setPrivateVariable: (obj) ->
    privateFunction(obj)

test = new Test("Test")
console.log(test.privateVariable)   # undefined
console.log(test.publicFunction())  # Test
test.setPrivateVariable("Changed!") #
console.log(test.publicFunction())  # Changed!

Это очень спорный вопрос. Мне лично нравится скрывать некоторые свойства и методы, чтобы сделать класс более понятным.