惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

GeekPlux

一代人的博客,一代人的青春注脚 那些年我打过的日结工 来美国的两年后 2023 一蓑烟雨 在美国拥有一辆 Tesla 的成本 我的 Workspaces 十年进化史 How to Sync Logseq Plugins, Themes and Settings Across Multiple Devices Setting Up Umami as Your Google Analytics Alternative: A Step-by-Step Guide 迁移豆瓣读书记录到 goodreads Enhance Your Internet Privacy in 2023 Refactor your blog comments system with Webmention.io 来美国之后,如何快速安顿下来 Three Levels of Information Perception 疫情三年 与人聊天的美好 我获取信息的方法 2022 版 我是如何学会编程的 Legacy code best practice: how to take over an existing project smoothly 2020 恍如隔世 接外包的一些坑和小技巧 论交友 往返香港隔离指南 即将失明,还能继续做程序员吗 小谈我对新技术的态度 How to use tailwindcss with AMP in a Next.js project 远程工作如何提高效率 复式记账、财报、量化与图论 我为什么从阿里巴巴离职 2019 柳暗花明 YouTube 观看历史数据分析 投资被动型指数基金正在造成下一次金融泡沫? 三种主流的网赚套利,躺着赚钱? 色盲的世界 我是如何管理 21 张信用卡的 薅羊毛的最大意义:保持对规则的敏感度 来香港的两个月 数据可视化技术实现的关键点 不需要扫描仪,数字化归档自己的文件 如何找到时薪 80 美元的远程工作(二) 如何找到时薪 80 美元的远程工作(一) 如何打造真正的简历 浅思图数据可视化 舍本逐末的学习方式 给想转行作程序员的人泼一盆冷水 算法优化人生之 —— 调度算法 杭州最适合闲来溜达的几条路线 2018 平淡无奇 突闻金庸先生逝世有感 十年博客折腾历史 数据可视化之 Sankey 桑基图的实现 研究生生涯总结 如何在不规则多边形内均匀撒点的算法 Web 前端中的增强现实(AR)开发技术 参加 Google Summer of Code 的体验 netjsongraph.js – Google Summer of Code (GSoC) 2017 summary 如何在 GitHub 上获得数百 stars Markvis - 在 markdown 中生成可视化图表 D3 force layout and WebGL integration 文本数据可视化(下)——一图胜千言 文本数据可视化(上)——从 Wordle 谈起 我获取信息的渠道 数据可视化基础——视觉编码 数据可视化基础——数据模型 数据可视化基础——可视化流程 为什么要用 Emacs Vega-Lite: A Grammar of Interactive Graphics 如何搭建一个私人网盘 如何阅读一篇学术论文 超过十个人的微信群根本没有价值 毕业后的两年 建立索引式的学习方法 为什么我喜欢写代码 写文章的小技巧 为什么文章写得好的人都很厉害 人总要有点盲目的自信 如何管理好自己的密码 Backbone View 之间通信的三种方式 Vim - 适合自己的,才是最好的 轻松玩转 Ukulele 告别社交网络有多难 双拼学习记 CoffeeScript 笔记 CSS 最核心的几个概念 响应式设计简易指南(译) 初识 TDD Collapsing margins——合并的外边距 菜鸟级 Mac 配置(二) 菜鸟级 Mac 配置(一) CSS 编写原则 Goodbye,我的大学 如何新建一个 Cocos2d-x 项目 Windows8.1 下 Cocos2d-x 环境搭建 Android 开发如何入门 如何绑定独立域名 写博客就用 FarBox 尝试改变微信公众账号消息的推送方式 情似流水 操作系统总结——存储器管理 操作系统总结——处理机管理 操作系统总结——引论
CoffeeScript 编码风格指南(译)
GeekPlux · 2014-06-21 · via GeekPlux

这份指南阐述了一些 CoffeeScript 的最佳实践和编码惯例。

这份指南是社群驱动的,非常鼓励大家来贡献内容。

请注意这还是一份正在完善的指南:仍有很多地方可以改进,有些已制定的准则也不一定是社区惯用的(基于此,在适当的情况下,这些有待斟酌的准则将有可能被修改或删除。)

灵感

本指南中的很多细节受到了几份现有的风格指南和其他资源的启发。特别是:

目录

代码布局(Code Layout)

Tab 还是 空格?(Tabs or Spaces?)

只用 空格,每级缩进均为 2 个空格。切勿混用 Tab 和空格。

最大行宽(Maximum Line Length)

限制每行最多 79 个字符。

空行(Blank Lines)

顶级函数和类的定义用一个空行分开。

类内部的函数定义也用一个空行分开。

对于每个函数体内,只在为了提高可读性的情况下才使用一个空行(例如:为了达到划分逻辑的目的)。

结尾空白(Trailing Whitespace)

不要在任何一行保留行尾空白。

可选的逗号(Optional Commas)

当对象(或数组)的属性(或元素)作为单独一行列出时,避免在换行符前使用逗号。如下:

# 好
foo = [
  'some'
  'string'
  'values'
]
bar:
  label: 'test'
  value: 87

# 差
foo = [
  'some',
  'string',
  'values'
]
bar:
  label: 'test',
  value: 87

编码(Encoding)

UTF-8 是首选的源文件编码。

模块导入(Module Imports)

如果需要导入模块 (CommonJS 模块,AMD,等等.), require 语句应该单独作为一行。如下:

require 'lib/setup'
Backbone = require 'backbone'

这些语句应该按以下顺序去分组:

  1. 标准库的导入 (如果标准库存在)
  2. 第三方库的导入
  3. 本地导入 (导入这个应用程序的或库的具体依赖)

表达式和语句中的空白(Whitespace in Expressions and Statements)

下列情况应该避免多余的空格:

  • 紧贴着圆括号、方括号和大括号内部

       ($ 'body') # 好
       ( $ 'body' ) # 差
    
  • 紧贴在逗号前

       console.log x, y # 好
       console.log x , y # 差
    

额外建议:

  • 在下列二元操作符的左右两边都保留 一个空格

    • 赋值运算符: =

      • 注意这同样适用于函数定义中的默认参数

        test: (param = null) -> # 好
        test: (param=null) -> # 差
        
    • 自增运算符: +=, -=, 等等。

    • 比较运算符: ==, <, >, <=, >=, unless, 等等。

    • 算术运算符: +, -, *, /, 等等。

    • (这些操作符两边的空格不要多于一个)

         # 好
         x = 1
         y = 1
         fooBar = 3
      
         # 差
         x      = 1
         y      = 1
         fooBar = 3
      

如果你修改了一段已有注释说明的代码,则也要更新它对应的注释。(理想状态是,重构这段代码直到它不需要注释说明,然后再把之前的注释全删掉。)

注释的首字母要大写,除非第一个单词是以小写字母开头的标识符。

如果注释很短,可以省略末尾的句号。

注释块通常应用于尾随其后的一段代码。

每一行注释都以 # 加一个空格开头,而且和被注释的代码有相同的缩进层次。

注释块内的段落以仅含单个 # 的行分割。

  # 这是一个块注释。请注意假如这是一段块注释,
  # 则它描述的就应该是接下来的这段代码。
  #
  # 这是块注释的第二段。
  # 请注意这段是由上一行带有 # 号的空行分开的。(P.S. 最好用英文写注释)

  init()
  start()
  stop()

行内注释紧贴在被描述的代码的上一行,如果行内注释足够短,则可以处在同一行行尾(由一个空格隔开)。

所有行内注释都以 # 加一个空格开头。

应该限制行内注释的使用,因为它们的存在通常是一个代码异味的标志。

不要给显而易见的情况作行内注释:

  # 差
  x = x + 1 # x 自增

然而,行内注释在某些情况下是有用的:

  # 好
  x = x + 1 # 边界补足

命名规范(Naming Conventions)

使用 小驼峰命名法 (第一个词的首字母小写,后面每个词的首字母大写)来命名所有的变量、方法和对象属性。

使用 大驼峰命名法 (第一个词的首字母,以及后面每个词的首字母都大写)来命名所有的类 (在其他类似的命名法中,这种风格通常也被称为 帕斯卡命名法(PascalCase)大写驼峰命名法(CamelCaps)首字母大写命名法(CapWords)。)

(CoffeeScript 官方 约定是用驼峰命名法,因为这可以简化与 JavaScript 的相互转化,想了解更多,请看这里.)

对于常量,单词全部大写,用下划线隔开即可:

CONSTANT_LIKE_THIS

私有函数和私有变量都应该在前面加一个下划线:

_privateMethod: ->

函数(Functions)

(以下这些准则同样适用于类中的方法。)

当声明一个带参函数时,应在参数列表的右圆括号后空出一个空格:

foo = (arg1, arg2) -> # 好
foo = (arg1, arg2)-> # 差

无参函数不要用圆括号:

bar = -> # 好
bar = () -> # 差

当函数链式调用,却在一行放不下时,则把每个函数调用都另起一行,且都缩进一级(即在 . 前加两个空格)。

[1..3]
  .map((x) -> x * x)
  .concat([10..12])
  .filter((x) -> x < 11)
  .reduce((x, y) -> x + y)

当调用函数时,我们应该为了提高可读性而去掉圆括号。请记住,「可读性」是我们主观臆断的。只有类似下面几个例子的情况才被社区认为是最佳的:

baz 12

brush.ellipse x: 10, y: 20 # 大括号在适当的时候也可以去掉

foo(4).bar(8)

obj.value(10, 20) / obj.value(20, 10)

print inspect value

new Tag(new Value(a, b), new Arg(c))

有时候你会发现圆括号用来包裹的是函数体(而不是函数的参数)。请看下面的例子(以下简称为「函数体风格」):

($ '#selektor').addClass 'klass'

(foo 4).bar 8

这段代码会编译为:

$('#selektor').addClass 'klass'

foo(4).bar 8

一些习惯链式调用的人会巧用「函数体风格」进行单独初始化:

($ '#selektor').addClass('klass').hide() # 单独初始化调用
(($ '#selektor').addClass 'klass').hide() # 全部调用

「函数体风格」并不得到推荐。但是, 当它适应一些特殊的项目需求时,还是得用它。

字符串(Strings)

用字符串插值代替字符串连接符:

"this is an #{adjective} string" # 好
"this is an " + adjective + " string" # 差

最好用单引号 ('') 而不是双引号 ("") 。除非是插入到另一段现有的字符串中(类似字符串插值)。

条件判断(Conditionals)

unless 来代替 if 的否定情况。

不要用 unless...else, 而用 if...else:

  # 好
  if true
    ...
  else
    ...

  # 差
  unless false
    ...
  else
    ...

多行的 if/else 语句应该缩进:

  # 好
  if true
    ...
  else
    ...

  # 差
  if true then ...
  else ...

循环和列表解析(Looping and Comprehensions)

尽可能的使用列表解析:

  # 好
  result = (item.name for item in array)

  # 差
  results = []
  for item in array
    results.push item.name

还可以过滤结果:

result = (item for item in array when item.name is "test")

遍历对象的键值:

object = one: 1, two: 2
alert("#{key} = #{value}") for key, value of object

扩展本地对象(Extending Native Objects)

不要修改本地对象。

比如,不要给 Array.prototype 引入 Array#forEach

异常(Exceptions)

不要抑制异常抛出。

注解(Annotations)

必要的时候应该写注解,来指明接下来的代码块具体将干什么。

注解应紧贴在被描述代码的上一行。

注解关键字后面应该跟一个冒号加一个空格,加一个描述性的注释。

  # FIXME: The client's current state should *not* affect payload processing.
  resetClientState()
  processPayload()

如果注解不止一行,则下一行缩进两个空格。

  # TODO: Ensure that the value returned by this call falls within a certain
  #   range, or throw an exception.
  analyze()

注解有以下几类:

  • TODO: 描述缺失的功能,以便日后加入
  • FIXME: 描述需要修复的代码
  • OPTIMIZE: 描述性能低下,或难以优化的代码
  • HACK: 描述一段值得质疑(或很巧妙)的代码
  • REVIEW: 描述需要确认其编码意图是否正确的代码

如果你必须自定义一个新的注解类型,则应该把这个注解类型记录在项目的 README 里面。

其他(Miscellaneous)

and 更优于 &&.

or 更优于 ||.

is 更优于 ==.

not 更优于 !.

or= 应在可能的情况下使用:

temp or= {} # 好
temp = temp || {} # 差

最好用 (::) 访问对象的原型:

Array::slice # 好
Array.prototype.slice # 差

最好用 @property 而不是 this.property.

return @property # 好
return this.property # 差

但是,避免使用 单独的 @:

return this # 好
return @ # 差

没有返回值的时候避免使用 return ,其他情况则需要显示 return 。

当函数需要接收可变数量的参数时,使用 splats (...)。

console.log args... # 好

(a, b, c, rest...) -> # 好

(译文完)