从CoffeeScript Ristretto查看以下内容:
QueueMaker = ->
do (queue = undefined) ->
array: []
head: 0
tail: -1
pushTail: (value) ->
queue.array[tail += 1] = value
pullHead: ->
unless queue.isEmpty()
do (value = queue.array[queue.head]) ->
queue.array[queue.head] = undefined
queue.head += 1
value
isEmpty: ->
queue.tail < queue.head
可以改变queue.head
- http://jsfiddle.net/VQLNG/。
queue = QueueMaker()
queue.head = 666
console.log queue
如何编写上述功能以使head
不公开?
答案 0 :(得分:1)
JavaScript没有私有属性,所以CoffeeScript也没有。
但是,在许多情况下,您可以通过使用函数作用域隐藏事物和闭包来访问隐藏的事物来模拟私有属性。
简单的堆栈实现应该演示该技术:
Stack = ->
stack = [ ]
push: (e) -> stack.push(e)
pop: -> stack.pop()
toArray: -> stack.slice()
stack
是Stack
函数中的局部变量,因此无法从外部Stack
访问或查看它。 push
和pop
函数只是代理stack
数组,而toArray
函数是查看stack
外观的唯一方法。只有这三个功能才能访问stack
,因此它实际上是私密的,每次拨打Stack
时,您都会获得一个新的本地stack
。
演示:http://jsfiddle.net/ambiguous/C8V5R/
调整您的队列以使用此技术隐藏array
,head
和tail
作为练习。
答案 1 :(得分:0)
QueueMaker
的返回值是一个JavaScript对象,其中head
是其中一个字段。对象字段是可变的,没有受保护状态的选项。
即使将QueueMaker
重写为CoffeeScript类,并将head作为实例变量,它仍然可以从对象范围之外变为可变。
CoffeeScript只能支持JavaScript的语言级功能,不支持私有/受保护的关键字。不幸的是
答案 2 :(得分:0)
QueueMaker = ->
do (array = [], head = 0, tail = -1) ->
pushTail: (value) ->
array[tail += 1] = value
pullHead: ->
if tail >= head
do (value = array[head]) ->
array[head] = undefined
head += 1
value
isEmpty: ->
tail < head
使用此版本时,会隐藏array
,head
和tail
。它们在创建queue
时初始化,并且只有存在时才保持存在。
coffee> queue = QueueMaker()
{ pushTail: [Function],
pullHead: [Function],
isEmpty: [Function] }
coffee> queue.head
undefined
但说实话,这是Ristretto链接上QueueMaker
的第一个版本。你给我们的是“de-encapsulate”
版本,故意重写以使这些变量可见(为了扩展其行为)。
作为参考,&#34; de-encapuslated&#34;版本是:
QueueMaker = ->
do (queue = undefined) ->
queue =
array: []
head: 0
tail: -1
pushTail: ...
pullHead: ...
您的问题省略了queue=
行。现在do()->
的目的应该更加明确。