Переменные экземпляра частного класса 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?
Ответы
Ответ 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!
Это очень спорный вопрос. Мне лично нравится скрывать некоторые свойства и методы, чтобы сделать класс более понятным.