推荐编码规范

下面是 Cocos Creator 开发团队使用的编码规范,收录在手册里以供游戏开发者和工具开发者参考。

命名规范

  • 当我们为变量,函数和实例命名时, 使用 camelCase 命名法。

    1. // bad
    2. const FOOBar = {};
    3. const foo_bar = {};
    4. function FOOBar () {}
    5. // good
    6. const fooBar = {};
    7. function fooBar () {}
  • 当变量、函数和实例命名涉及到缩写时,缩写在开头全部小写,在后续单词中,则全部大写。

    1. // bad
    2. const Id = 0;
    3. const iD = 0;
    4. function requireId () {}
    5. // good
    6. const id = 0;
    7. const uuid = '';
    8. function requireID () {}
    9. class AssetUUID {}
  • 当我们为类或者模块命名时,使用 PascalCase 命名法。

    1. // bad
    2. const foobar = cc.Class({
    3. foo: 'foo',
    4. bar: 'bar',
    5. });
    6. const foobar = require('foo-bar');
    7. // good
    8. const FooBar = cc.Class({
    9. foo: 'foo',
    10. bar: 'bar',
    11. });
    12. const FooBar = require('foo-bar');
  • 推荐使用全大写加下划线来命名“常量”。

    1. // bad
    2. const PRIVATE_VARIABLE = 'should not be unnecessarily uppercased within a file';
    3. // bad
    4. var THING_TO_BE_CHANGED = 'should obviously not be uppercased';
    5. // bad
    6. let REASSIGNABLE_VARIABLE = 'do not use let with uppercase variables';
    7. // ---
    8. // allowed but does not supply semantic value
    9. export const apiKey = 'SOMEKEY';
    10. // better in most cases
    11. export const API_KEY = 'SOMEKEY';
    12. // ---
    13. // bad - unnecessarily uppercases key while adding no semantic value
    14. export const MAPPING = {
    15. KEY: 'value'
    16. };
    17. // good
    18. export const Type = {
    19. SIMPLE: 'value'
    20. };
  • 使用前置下划线 _ 当我们为私有属性命名

    1. // bad
    2. this.__firstName__ = 'foobar';
    3. this.firstName_ = 'foobar';
    4. // good
    5. this._firstName = 'foobar';
  • 文件名我们采用 dash 命名法

    1. // bad
    2. fooBar.js
    3. FooBar.js
    4. // good
    5. foo-bar.js

语法规范

  • 当类的属性声明没有初始化式的时候,应当声明 declare,否则可能面临性能问题。详情请参考 Issue

    1. // bad
    2. class A {
    3. public a: number;
    4. constructor (a : number) {
    5. // 相当于此处还有一句 this.a = void 0;
    6. // 注意可能面临性能问题!
    7. this.a = a;
    8. }
    9. }
    10. // good
    11. class A {
    12. public a: number = 0; // Ok.
    13. constructor (a : number) {
    14. // 相当于此处还有一句 this.a = 0;
    15. // 但不会引起大的性能问题
    16. this.a = a;
    17. }
    18. }
    19. // best
    20. class A {
    21. public declare a: number;
    22. public b: undefined | object; // OK: b 未在构造函数中二次赋值
    23. public declare c: object | null;
    24. constructor (a: number, c: object) {
    25. this.a = a;
    26. this.c = c;
    27. }
    28. }
  • 使用 Object.create(null) 创建一个字典

    1. // bad
    2. const map = new Object();
    3. // bad
    4. const map = {};
    5. // good
    6. const map = Object.create(null);
  • 使用 [] 创建一个数组

    1. // bad
    2. const array = new Array();
    3. // good
    4. const array = [];
  • 尽可能在 TypeScript 代码中使用单引号 '' 来定义 string

    1. // bad
    2. const str = "Hello World";
    3. // good
    4. const str = 'Hello World';
  • 多行 string 定义时, 尽可能使用 + 定义

    1. // bad
    2. const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
    3. // bad
    4. const errorMessage = 'This is a super long error that was thrown because \
    5. of Batman. When you stop to think about how Batman had anything to do \
    6. with this, you would get nowhere \
    7. fast.';
    8. // good
    9. const errorMessage = 'This is a super long error that was thrown because ' +
    10. 'of Batman. When you stop to think about how Batman had anything to do ' +
    11. 'with this, you would get nowhere fast.';
  • 使用 ===!== 而不是 ==!=

书写规范

  • 根据个人习惯, 和原代码作者格式, 选择 4 个空格或者 2 个空格作为缩进

    1. // bad
    2. function () {
    3. const name;
    4. }
    5. // very bad
    6. function () {
    7. ∙∙<tab>∙∙const name;
    8. }
    9. // good
    10. function () {
    11. ∙∙const name;
    12. }
    13. // good
    14. function () {
    15. ∙∙∙∙const name;
    16. }
  • 行尾不要留有空格,文件底部请留一个空行

    1. // bad
    2. function () {∙
    3. ∙∙∙∙const name;∙
    4. }
    5. /* EOF */
    6. // good
    7. function () {
    8. ∙∙∙∙const name;
    9. }
    10. /* EOF */
  • 语句结尾请加 ;

    1. // bad
    2. proto.foo = function () {
    3. }
    4. // good
    5. proto.foo = function () {
    6. };
    7. // bad
    8. function foo () {
    9. return 'test'
    10. }
    11. // very bad
    12. // returns `undefined` instead of the value on the next line,
    13. // always happens when `return` is on a line by itself because of Automatic Semicolon Insertion!
    14. function foo () {
    15. return
    16. 'test'
    17. }
    18. // good
    19. function foo () {
    20. return 'test';
    21. }
    22. // bad
    23. function foo () {
    24. };
    25. // good,这里不是语句结尾
    26. function foo () {
    27. }
  • 尽可能将 { 和表达式放在同一行

    1. // bad
    2. if ( isFoobar )
    3. {
    4. }
    5. // good
    6. if ( isFoobar ) {
    7. }
    8. // bad
    9. function foobar ()
    10. {
    11. }
    12. // good
    13. function foobar () {
    14. }
    15. // bad
    16. const obj =
    17. {
    18. foo: 'foo',
    19. bar: 'bar',
    20. }
    21. // good
    22. const obj = {
    23. foo: 'foo',
    24. bar: 'bar',
    25. }
  • { 前请空一格

    1. // bad
    2. if (isJedi){
    3. fight();
    4. }
    5. else{
    6. escape();
    7. }
    8. // good
    9. if (isJedi) {
    10. fight();
    11. } else {
    12. escape();
    13. }
    14. // bad
    15. dog.set('attr',{
    16. age: '1 year',
    17. breed: 'Bernese Mountain Dog',
    18. });
    19. // good
    20. dog.set('attr', {
    21. age: '1 year',
    22. breed: 'Bernese Mountain Dog',
    23. });
  • 在逻辑状态表达式 ( if, else, while, switch) 后请空一格

    1. // bad
    2. if(isJedi) {
    3. fight ();
    4. }
    5. else{
    6. escape();
    7. }
    8. // good
    9. if (isJedi) {
    10. fight();
    11. } else {
    12. escape();
    13. }
  • 二元、三元运算符的左右请空一格

    1. // bad
    2. const x=y+5;
    3. const left = rotated? y: x;
    4. // good
    5. const x = y + 5;
    6. const left = rotated ? y : x;
    7. // bad
    8. for (let i=0; i< 10; i++) {
    9. }
    10. // good
    11. for (let i = 0; i < 10; i++) {
    12. }
  • 一些函数的声明方式

    1. // bad
    2. const test = function () {
    3. console.log('test');
    4. };
    5. // good
    6. function test () {
    7. console.log('test');
    8. }
    9. // bad
    10. function test () { console.log('test'); };
    11. // good
    12. function test () {
    13. console.log('test');
    14. }
    15. // bad
    16. function divisibleFunction () {
    17. return DEBUG ? 'foo' : 'bar';
    18. }
    19. // best
    20. const divisibleFunction = DEBUG ?
    21. function () {
    22. return 'foo';
    23. } :
    24. function () {
    25. return 'bar';
    26. };
    27. // bad
    28. function test(){
    29. }
    30. // good
    31. function test () {
    32. }
    33. // bad
    34. const obj = {
    35. foo: function () {
    36. }
    37. };
    38. // good
    39. const obj = {
    40. foo () {
    41. }
    42. };
    43. // bad
    44. array.map(x=>x + 1);
    45. array.map(x => {
    46. return x + 1;
    47. });
    48. // good
    49. array.map(x => x + 1);
  • 在 Block 定义之间请空一行

    1. // bad
    2. if (foo) {
    3. return bar;
    4. }
    5. return baz;
    6. // good
    7. if (foo) {
    8. return bar;
    9. }
    10. return baz;
    11. // bad
    12. const obj = {
    13. x: 0,
    14. y: 0,
    15. foo () {
    16. },
    17. bar () {
    18. },
    19. };
    20. return obj;
    21. // good
    22. const obj = {
    23. x: 0,
    24. y: 0,
    25. foo () {
    26. },
    27. bar () {
    28. },
    29. };
    30. return obj;
  • 不要使用前置逗号定义

    1. // bad
    2. const story = [
    3. once
    4. , upon
    5. , aTime
    6. ];
    7. // good
    8. const story = [
    9. once,
    10. upon,
    11. aTime,
    12. ];
    13. // bad
    14. const hero = {
    15. firstName: 'Ada'
    16. , lastName: 'Lovelace'
    17. , birthYear: 1815
    18. , superPower: 'computers'
    19. };
    20. // good
    21. const hero = {
    22. firstName: 'Ada',
    23. lastName: 'Lovelace',
    24. birthYear: 1815,
    25. superPower: 'computers',
    26. };
  • 单行注释请在斜杠后面加一个空格

    1. //bad
    2. // good
  • 多行注释写法

    1. /*
    2. * good
    3. */
  • 需要导出到 API 文档的多行注释写法

    1. /**
    2. * good
    3. */
  • 除了多语言 API 注释以外,代码中不允许写中文注释

    1. // bad
    2. // 中文注释不利于非中文开发者阅读代码
    3. // good
    4. // Please write all in file comments in English

推荐阅读

Airbnb ts Style Guide