在 Coffeescript 中避免命名冲突的最佳实践

Best practices to avoid naming clashes in Coffeescript

问题

在 Coffeescript 中避免命名冲突的最佳做法是什么,尤其是考虑到嵌套范围和 Ajax 回调的上下文?

我的问题

我遇到了名称冲突问题,我的命名约定规定 Ajax 回调中的数据名称与我范围内的另一个对象相同。

在下面的代码中,我将我的所有函数都放在对象 notifications 上,但是来自我的 Ajax GET 请求的数据被命名为 notifications。结果明显报错:

# Handles initial get request.
notifications.init = ->
$.ajax 'notifications',
  type: 'GET'
  dataType: 'json'
  error: (jqXHR, textStatus, errorThrown) ->
    alert textStatus
  success: (notifications, textStatus, jqXHR) ->
    if notifications?
      filteredNotifications = notifications.filteredNotifications notifications
      notifications.behavior notifications

# Triggers the notifications
notifications.behavior = (filteredNotifications) ->
  if filteredNotifications?
    $('#counter').html filteredNotifications.length
  if parseInt($('#counter').html()) > 0
    $('#counter').css
      'background': 'black'

# Removes notifications sent by the current user, copies for the other user,
# and notifications marked as observed.
notifications.filteredNotifications = (notifications) ->
  filteredNotifications = filteredNotifications.filter((notification) ->
    notification.recipients.username is $username() and
    notification.copy_for_user_id is $id() and
    notification.observed is false
  )
  return filteredNotifications

注意事项

我考虑过 Ajax 回调中数据对象的 notifications 的各种缩写,但它降低了可读性。以不同的方式命名父对象似乎也不合适。

这是我的推介。正如您所说,这个主题非常主观,但我尽量保持这个标准。

两大要点:

  • 从名称空间中抽象出逻辑是一种很好的做法,可以减少与之冲突的符号。 Coffeescript 允许您实例化匿名 类,这对此有很大帮助。
  • 我专门使用标识符 data 作为 JSON 回调中数据对象的名称。这减少了任何阅读回调的人的困惑,并有助于消除像您遇到的那样的冲突。

    notifications = new class
        init: -> $.ajax 'notifications',
            type: 'GET'
            dataType: 'json'
            error: (jqXHR, textStatus, errorThrown) ->
                alert textStatus
            success: (data, textStatus, jqXHR) =>
                if data?
                    @behavior @filter data
    
        # Triggers the notifications
        behavior: (notifications) ->
            if notifications?
                $('#counter').html notifications.length
                if notifications.length?
                    $('#counter').css
                        'background': 'black'
                return
    
        # Removes notifications sent by the current user, copies for the other user,
        # and notifications marked as observed.
        filter: (notifications) ->
            return notifications.filter (notification) ->
                notification.recipients.username is $username() and
                notification.copy_for_user_id is $id() and
                notification.observed is false
    
    notifications.init()
    

我做了一些其他的小改动,我冒昧地在 behavior 中进行了逻辑更改,这可能不适合您的情况,但无论如何您一定要修改那里的逻辑。使用 DOM 来存储您在应用程序逻辑中需要的值是不明智的。

需要注意的重要一点是 "fat arrow" (=>) 在 success 回调中的使用。它是必需的,因此您可以将函数绑定到正确的上下文并使 @behavior@filter 正确解析。