請造訪 Apache ECharts 官方網站:

https://echarts.dev.org.tw
造訪官方網站
x

程式碼標準

當您為 ECharts 專案貢獻時,請遵循此標準。

Apache EChartsTM

程式碼風格

檔案

[必須] JavaScript 原始碼檔案必須使用 UTF-8 編碼,且不得包含 BOM。

縮排

[必須] 使用 4 個空格縮排。不允許使用 tab 和 2 個空格縮排。

[必須] switch 中的 casedefault 必須縮排。

// good
switch (variable) {
    case '1':
        // do...
        break;
    case '2':
        // do...
        break;
    default:
        // do...
}

// bad
switch (variable) {
case '1':
    // do...
    break;
case '2':
    // do...
    break;
default:
    // do...
}

空格

[必須] 使用空格分隔二元運算子。但一元運算子和其運算元之間不得有空格。

let a = !arr.length;
a++;
a = b + c;

[必須] 在前導大括號前放置 1 個空格。

// good

if (condition) {
}

set('attr', {
    some: 'xxx',
    any: 'yyy'
});

function funcName() {
}


// bad

if (condition){
}

set('attr',{
    some: 'xxx',
    any: 'yyy'
});

function funcName(){
}

[必須]if / else / for / while / function / switch / do / try / catch / finally 之後放置 1 個空格。

// good

if (condition) {
}

while (condition) {
}

(function () {
})();


// bad

if(condition) {
}

while(condition) {
}

(function() {
})();

[必須] 在物件建立陳述式中,在 : 之後放置 1 個空格,但在其之前不得有空格。

// good
const obj = {
    a: 1,
    b: 2,
    c: 3
};

// bad
const obj = {
    a : 1,
    b:2,
    c :3
};

[必須] 在函式宣告、具名函式表達式和函式呼叫中,函式名稱和 ( 之間不得有空格。

// good

function funcName() {
}

const funcName = function funcName() {
};

funcName();


// bad

function funcName () {
}

const funcName = function funcName () {
};

funcName ();

[必須],; 之間不得有空格。

// good
callFunc(a, b);

// bad
callFunc(a , b) ;

[必須]([ 之後,以及 )] 之前不得有空格。

// good

callFunc(param1, param2, param3);

save(this.list[this.indexes[i]]);

needIncream && (variable += increament);

if (num > list.length) {
}

while (len--) {
}


// bad

callFunc( param1, param2, param3 );

save( this.list[ this.indexes[ i ] ] );

needIncreament && ( variable += increament );

if ( num > list.length ) {
}

while ( len-- ) {
}


// good
const arr1 = [];
const arr2 = [1, 2, 3];
const obj1 = {};
const obj2 = {name: 'obj'};
const obj3 = {
    name: 'obj',
    age: 20,
    sex: 1
};

// bad
const arr1 = [ ];
const arr2 = [ 1, 2, 3 ];
const obj1 = { };
const obj2 = { name: 'obj' };
const obj3 = {name: 'obj', age: 20, sex: 1};

[必須] 每行結尾不得有額外空格。

換行

[必須] 在陳述式結尾處換行。

[必須] 每行不得超過 120 個字元。

[必須] 如果運算子需要換行,則應將其放置在行的開頭。

// good
if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
    || user.hasAuthority('delete-admin')
) {
    // Code
}

const result = number1 + number2 + number3
    + number4 + number5;


// bad
if (user.isAuthenticated() &&
    user.isInRole('admin') &&
    user.hasAuthority('add-admin') ||
    user.hasAuthority('delete-admin')) {
    // Code
}

const result = number1 + number2 + number3 +
    number4 + number5;

[必須] 如果括號內的內容佔據多行,則 )]} 應另起新行。其縮排應與對應的 ([{ 所在的行相同。

// good
if (product) {
    product.load();
    if (user.isAuthenticated()
        && user.isInRole('admin')
        && user.hasAuthority('add-admin')
    ) {
        sendProduct(user, product);
    }
}
const arr = [
    'candy', 'sugar'
];

// bad
if (product) {
    product.load();
    if (user.isAuthenticated()
        && user.isInRole('admin')
        && user.hasAuthority('add-admin')) {
        sendProduct(user, product);
    }
}
const arr = [
        'candy', 'sugar'
    ];

[必須] 不得在 ,; 之前換行。

// good
const obj = {
    a: 1,
    b: 2,
    c: 3
};

foo(
    aVeryVeryLongArgument,
    anotherVeryLongArgument,
    callback
);


// bad
const obj = {
    a: 1
    , b: 2
    , c: 3
};

foo(
    aVeryVeryLongArgument
    , anotherVeryLongArgument
    , callback
);

[建議] 關於換行和縮排的建議

if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
) {
    // Code
}

foo(
    aVeryVeryLongArgument,
    anotherVeryLongArgument,
    callback
);

baidu.format(
    dateFormatTemplate,
    year, month, date, hour, minute, second
);

$('#items')
    .find('.selected')
    .highlight()
    .end();

const result = thisIsAVeryVeryLongCondition
    ? resultA : resultB;

const res = condition
    ? thisIsAVeryVeryLongResult
    : resultB;

[必須] 如果使用多行區塊,則 elsecatch 應另起新行。

// good

if (condition) {
    // some statements;
}
else {
    // some statements;
}

try {
    // some statements;
}
catch (ex) {
    // some statements;
}


// bad

if (condition) {
    // some statements;
} else {
    // some statements;
}

try {
    // some statements;
} catch (ex) {
    // some statements;
}

陳述式

[必須] 陳述式結尾不得忽略分號。

[必須] 即使只有一行程式碼,也不得忽略 {}

// good
if (condition) {
    callFunc();
}

// bad
if (condition) callFunc();
if (condition)
    callFunc();

[必須] 在函式定義結尾不得放置分號。

// good
function funcName() {
}

// bad
function funcName() {
};

// For function expression, the semicolon must not be ignored.
const funcName = function () {
};

[必須] 在物件和陣列宣告中,不得使用尾隨逗號。

// good

const obj = {
    attr1: 'xxx',
    attr2: 'yyy'
};

const arr = [
    'xxx',
    'yyy'
];


// bad

const obj = {
    attr1: 'xxx',
    attr2: 'yyy',
};

const arr = [
    'xxx',
    'yyy',
];

命名慣例

[必須] 變數、屬性和函式名稱應使用 lowerCamelCase (小駝峰式命名法)。

const loadingModules = {};
function loadProduct() {
}

[必須] 類別名稱應使用 UpperCamelCase (Pascal 命名法)。

function Element(options) {
}

[建議] 縮寫的所有字母應全部大寫或全部小寫。

function parseSVG() {
}
const svgParser;

語言特性

相容性

語言特性可以透過某些工具進行 polyfill (墊片) 來支援,但不得修改內建 JS 物件的原型。

// good

import * as zrUtil from 'zrender/src/core/util';

zrUtil.each(array, function (val, index) {
    sum += val;
});

const result = zrUtil.map(array, function (val) {
    return parse(val);
});

const pos = zrUtil.indexOf(array, val);

const obj2 = zrUtil.extend({}, obj1);

function Element() {
    // ...
}


// bad

array.forEach(function (val, index) {
    sum += val;
});

let result = array.map(function (val) {
    return parse(val);
});

const pos = array.indexOf(val);

const obj2 = Object.assign({}, obj1);

class Element {
    // ...
}

String.prototype.trim = function () {
};

變數

[必須] 宣告變數時,優先使用 const。且一行程式碼不得宣告多個變數。

// good
const name = 'MyName';
const hangModules = [];
const missModules = [];
const visited = {};

// bad
name = 'MyName';
const hangModules = [],
    missModules = [],
    visited = {};

條件

[必須] 在相等運算式中,== 只能用於 nullundefined 的偵測。其餘情況應使用 ===

// good
if (age === 30) {
    // ...
}
if (type == null) {
    // ...
}

// bad
if (age == 30) {
    // ......
}

[建議] 使用 xxx == null 來判斷 nullundefined

[建議] 盡量使 nullundefined 的意義相同,也就是說,不要讓使用者或開發人員區分變數是 null 還是 undefined

[建議] 函式表達式或函式宣告不應放置在迴圈體內。

// good
function clicker() {
    // ......
}

for (let i = 0, len = elements.length; i < len; i++) {
    const element = elements[i];
    addListener(element, 'click', clicker);
}


// bad
for (let i = 0, len = elements.length; i < len; i++) {
    const element = elements[i];
    addListener(element, 'click', function () {});
}

類型轉換

[建議] 使用 + '' 將值轉換為字串。

// good
num + '';

// bad
new String(num);
num.toString();
String(num);

[建議] 使用 + 將值轉換為數字。

// good
+str;

// bad
Number(str);

[必須] 使用 parseInt 時,不得忽略第二個參數。

// good
parseInt(str, 10);

// bad
parseInt(str);

字串、物件、陣列

[必須] 使用 ' 而非 " 來定義字串。

[必須] 使用物件字面值 {} 來建立普通物件。

// good
const obj = {};

// bad
const obj = new Object();

[必須] 如果物件字面值的所有屬性都不需要引號,則應忽略它們。如果需要引號,請使用 ' 而非 "

// good
const info = {
    name: 'someone',
    age: 28
};

// bad
const info = {
    'name': 'someone',
    'age': 28
};
const info2 = {
    "age": 40
};

[必須] 不得修改內建物件的原型。

// Forbidden
String.prototype.trim = function () {
};

[建議] 盡量使用 . 而非 [] 來存取物件的屬性。

[建議] 當使用 for ... in ... 時,應使用 hasOwnProperty,以防某些執行環境中在 Object 的原型上新增了額外的屬性。

const newInfo = {};
for (const key in info) {
    if (info.hasOwnProperty(key)) {
        newInfo[key] = info[key];
    }
}

[必須] 使用陣列字面值 [] 來建立陣列,除非打算建立具有指定長度的陣列。

// good
const arr = [];
const arr2 = new Array(1e4);

// bad
const arr = new Array();

[必須] 在陣列遍歷中,請勿使用 for in

其他

[必須] 請勿使用 evalwith。可以使用 new Function