推荐编码规范
下面是 Cocos Creator 开发团队使用的编码规范,收录在手册里以供游戏开发者和工具开发者参考。
命名规范
当我们为变量,函数和实例命名时, 使用 camelCase 命名法。
// bad
const FOOBar = {};
const foo_bar = {};
function FOOBar () {}
// good
const fooBar = {};
function fooBar () {}
当变量、函数和实例命名涉及到缩写时,缩写在开头全部小写,在后续单词中,则全部大写。
// bad
const Id = 0;
const iD = 0;
function requireId () {}
// good
const id = 0;
const uuid = '';
function requireID () {}
class AssetUUID {}
当我们为类或者模块命名时,使用 PascalCase 命名法。
// bad
const foobar = cc.Class({
foo: 'foo',
bar: 'bar',
});
const foobar = require('foo-bar');
// good
const FooBar = cc.Class({
foo: 'foo',
bar: 'bar',
});
const FooBar = require('foo-bar');
推荐使用全大写加下划线来命名“常量”。
// bad
const PRIVATE_VARIABLE = 'should not be unnecessarily uppercased within a file';
// bad
var THING_TO_BE_CHANGED = 'should obviously not be uppercased';
// bad
let REASSIGNABLE_VARIABLE = 'do not use let with uppercase variables';
// ---
// allowed but does not supply semantic value
export const apiKey = 'SOMEKEY';
// better in most cases
export const API_KEY = 'SOMEKEY';
// ---
// bad - unnecessarily uppercases key while adding no semantic value
export const MAPPING = {
KEY: 'value'
};
// good
export const Type = {
SIMPLE: 'value'
};
使用前置下划线
_
当我们为私有属性命名// bad
this.__firstName__ = 'foobar';
this.firstName_ = 'foobar';
// good
this._firstName = 'foobar';
文件名我们采用 dash 命名法
// bad
fooBar.js
FooBar.js
// good
foo-bar.js
语法规范
当类的属性声明没有初始化式的时候,应当声明 declare,否则可能面临性能问题。详情请参考 Issue
// bad
class A {
public a: number;
constructor (a : number) {
// 相当于此处还有一句 this.a = void 0;
// 注意可能面临性能问题!
this.a = a;
}
}
// good
class A {
public a: number = 0; // Ok.
constructor (a : number) {
// 相当于此处还有一句 this.a = 0;
// 但不会引起大的性能问题
this.a = a;
}
}
// best
class A {
public declare a: number;
public b: undefined | object; // OK: b 未在构造函数中二次赋值
public declare c: object | null;
constructor (a: number, c: object) {
this.a = a;
this.c = c;
}
}
使用
Object.create(null)
创建一个字典// bad
const map = new Object();
// bad
const map = {};
// good
const map = Object.create(null);
使用
[]
创建一个数组// bad
const array = new Array();
// good
const array = [];
尽可能在 TypeScript 代码中使用单引号
''
来定义 string// bad
const str = "Hello World";
// good
const str = 'Hello World';
多行 string 定义时, 尽可能使用
+
定义// bad
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.';
// bad
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.';
// good
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.';
使用
===
和!==
而不是==
和!=
书写规范
根据个人习惯, 和原代码作者格式, 选择 4 个空格或者 2 个空格作为缩进
// bad
function () {
∙const name;
}
// very bad
function () {
∙∙<tab>∙∙const name;
}
// good
function () {
∙∙const name;
}
// good
function () {
∙∙∙∙const name;
}
行尾不要留有空格,文件底部请留一个空行
// bad
function () {∙
∙∙∙∙const name;∙
}
/* EOF */
// good
function () {
∙∙∙∙const name;
}
/* EOF */
语句结尾请加
;
// bad
proto.foo = function () {
}
// good
proto.foo = function () {
};
// bad
function foo () {
return 'test'
}
// very bad
// returns `undefined` instead of the value on the next line,
// always happens when `return` is on a line by itself because of Automatic Semicolon Insertion!
function foo () {
return
'test'
}
// good
function foo () {
return 'test';
}
// bad
function foo () {
};
// good,这里不是语句结尾
function foo () {
}
尽可能将
{
和表达式放在同一行// bad
if ( isFoobar )
{
}
// good
if ( isFoobar ) {
}
// bad
function foobar ()
{
}
// good
function foobar () {
}
// bad
const obj =
{
foo: 'foo',
bar: 'bar',
}
// good
const obj = {
foo: 'foo',
bar: 'bar',
}
在
{
前请空一格// bad
if (isJedi){
fight();
}
else{
escape();
}
// good
if (isJedi) {
fight();
} else {
escape();
}
// bad
dog.set('attr',{
age: '1 year',
breed: 'Bernese Mountain Dog',
});
// good
dog.set('attr', {
age: '1 year',
breed: 'Bernese Mountain Dog',
});
在逻辑状态表达式 (
if
,else
,while
,switch
) 后请空一格// bad
if(isJedi) {
fight ();
}
else{
escape();
}
// good
if (isJedi) {
fight();
} else {
escape();
}
二元、三元运算符的左右请空一格
// bad
const x=y+5;
const left = rotated? y: x;
// good
const x = y + 5;
const left = rotated ? y : x;
// bad
for (let i=0; i< 10; i++) {
}
// good
for (let i = 0; i < 10; i++) {
}
一些函数的声明方式
// bad
const test = function () {
console.log('test');
};
// good
function test () {
console.log('test');
}
// bad
function test () { console.log('test'); };
// good
function test () {
console.log('test');
}
// bad
function divisibleFunction () {
return DEBUG ? 'foo' : 'bar';
}
// best
const divisibleFunction = DEBUG ?
function () {
return 'foo';
} :
function () {
return 'bar';
};
// bad
function test(){
}
// good
function test () {
}
// bad
const obj = {
foo: function () {
}
};
// good
const obj = {
foo () {
}
};
// bad
array.map(x=>x + 1);
array.map(x => {
return x + 1;
});
// good
array.map(x => x + 1);
在 Block 定义之间请空一行
// bad
if (foo) {
return bar;
}
return baz;
// good
if (foo) {
return bar;
}
return baz;
// bad
const obj = {
x: 0,
y: 0,
foo () {
},
bar () {
},
};
return obj;
// good
const obj = {
x: 0,
y: 0,
foo () {
},
bar () {
},
};
return obj;
不要使用前置逗号定义
// bad
const story = [
once
, upon
, aTime
];
// good
const story = [
once,
upon,
aTime,
];
// bad
const hero = {
firstName: 'Ada'
, lastName: 'Lovelace'
, birthYear: 1815
, superPower: 'computers'
};
// good
const hero = {
firstName: 'Ada',
lastName: 'Lovelace',
birthYear: 1815,
superPower: 'computers',
};
单行注释请在斜杠后面加一个空格
//bad
// good
多行注释写法
/*
* good
*/
需要导出到 API 文档的多行注释写法
/**
* good
*/
除了多语言 API 注释以外,代码中不允许写中文注释
// bad
// 中文注释不利于非中文开发者阅读代码
// good
// Please write all in file comments in English