单例在JS/coffeescript中引用自身的优雅方式

Elegant way for a singleton to reference itself in JS/coffeescript?

本文关键字:方式 引用 JS coffeescript 单例      更新时间:2023-09-26

我正在创建一个由单例组成的模块,该模块旨在存储数据:

context =
    c:@
    selected:
        sketch: undefined
        points: []
        edges: []
    hovered:
        points: []
        edges: []
    ###Note: Perhaps later I can make a more elegant naming scheme
    say, specifying subobjects such as context.select.sketch(<sketch>)###
    select:
        sketch: (sketch)->
            c.selected.sketch = sketch
            return
        node: (point)->
            c.selected.points.push point
    deselectAll: ->
        ###Clear all arrays ###
        c.selected.points.length = 0
        c.selected.edges.length = 0

我希望选择包含用于访问selected子对象内属性的方法。但是,与闭包不同,我不能将this存储在命名变量中,也无法从context.select内部访问context,因为this将引用context.select

如何建立对父/根对象的引用以在子对象中使用?

我鼓励你创建没有命名空间的类以提高可读性。你在这里,你:

# please use class syntax as a vessel to create singleton
# you may declare class and then call new and assign it's instance to avariable 
# or, since it's a singleton, you can do that in one line
window.Context = new class Context
# constructor function should init the object
constructor: ->
    @selected =
      sketch: undefined
      points: []
      edges: []
    @hovered =
      points: []
      edges: []
    # convenience namespace, just referring to class methods
    @select =
      sketch: @selectSketch
      node: @selectNode
  # not having namespaces adds a lot to clarity of the class
  selectSketch: (sketch) =>
    # no need to call return here
    @selected.sketch = sketch
  selectNode: (point) =>
    @selected.points.push point
  # you probably want to assign new array rather then reset the length 
  deselectAll: =>
    @selected.points = []
    @selected.edges = []