Vico Bill< 刘 利 波 > 的个人网站

记录关于学习、工作中的技术点滴

C,C++,Rust,Ruby爱好者;热衷于游戏开发、任务自动化与跨平台;沉迷于游戏引擎与图形表现;深信'简单、多元'哲学的力量。


访问主页

编程语言-Javascript编码规范

命名规范

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

     // bad
     var FOOBar = {};
     var foo_bar = {};
     function FOOBar () {}
      
     // good
     var fooBar = {};
     function fooBar () {}
    
  • 当我们为类或者模块命名时, 使用 PascalCase 命名法.

     // bad
     var foobar = cc.Class({
         foo: 'foo',
         bar: 'bar',
     });
     var foobar = require('foo-bar');
      
     // good
     var FooBar = cc.Class({
         foo: 'foo',
         bar: 'bar',
     });
     var FooBar = require('foo-bar');
    
  • 使用前置下划线 _ 当我们为私有属性命名

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

     // bad
     fooBar.js
     FooBar.js
      
     // good
     foo-bar.js
    

语法规范

  • 使用 {} 创建一个字典

     // bad
     var map = new Object();
      
     // bad
     var map = Object.create(null);
      
     // good
     var map = {};
    
  • 使用 [] 创建一个数组

     // bad
     var array = new Array();
      
     // good
     var array = [];
    
  • 尽可能在 js 代码中使用单引号 '' 来定义 string

     // bad
     var str = "Hello World";
      
     // good
     var 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() {
     var name;
     }
      
     // very bad
     function() {
     ∙∙<tab>∙∙var name;
     }
      
     // good
     function() {
     ∙∙var name;
     }
      
     // good
     function() {
     ∙∙∙∙var name;
     }
    
  • 行尾不要留有空格,文件底部请留一个空行

     // bad
     function () {
     ∙∙∙∙var name;
     }
     /* EOF */
      
     // good
     function () {
     ∙∙∙∙var name;
     }
      
     /* EOF */
    
  • 语句结尾请加 ;

     // bad
     proto.foo = function () {
     }
      
     // good
     proto.foo = function () {
     };
      
     // very bad
     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
     var obj =
     {
         foo: 'foo',
         bar: 'bar',
     }
      
     // good
     var 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
     var x=y+5;
     var left = rotated? y: x;
      
     // good
     var x = y + 5;
     var left = rotated ? y : x;
      
     // bad
     for (let i=0; i< 10; i++) {
     }
      
     // good
     for (let i = 0; i < 10; i++) {
     }
    
  • 一些函数的声明方式,尽量有空格分隔,保持代码清晰度:

     // bad
     var test = function () {
         console.log('test');
     };
      
     // good
     function test () {
         console.log('test');
     }
      
     // bad
     function divisibleFunction () {
         return DEBUG ? 'foo' : 'bar';
     }
      
     // good
     var divisibleFunction = DEBUG ?
         function () {
             return 'foo';
         } :
         function () {
             return 'bar';
         };
      
     // bad
     function test(){
     }
      
     // good
     function test () {
     }
      
     // bad
     var obj = {
         foo: function () {
         }
     };
      
     // good
     var obj = {
         foo () {
         }
     };
      
     // bad
     array.map(x=>x + 1);
     array.map(x => {
         return x + 1;
     });
      
     // good
     array.map(x => x + 1);
    
  • 在 代码块定义之间请空一行

     // 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
     var story = [
           once
         , upon
         , aTime
     ];
      
     // good
     var story = [
         once,
         upon,
         aTime,
     ];
      
     // bad
     var hero = {
           firstName: 'Ada'
         , lastName: 'Lovelace'
         , birthYear: 1815
         , superPower: 'computers'
     };
      
     // good
     var hero = {
         firstName: 'Ada',
         lastName: 'Lovelace',
         birthYear: 1815,
         superPower: 'computers',
     };
    
  • 单行注释请在斜杠后面加一个空格

     //bad
     // good
    
  • 多行注释写法

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

     /**
      * good
      */
    

其他杂项:

  • var通常声明全局变量,尽可能多地使用let。

  • const为常量,常量命名方式全大写分隔形式:

    const A_CONST_VAL = 100;
    
  • 对于bool型函数或变量,使用is,has,can等等表示判断的单词为前缀:

    let isDead = false;
      
    function isGameOver() {return false;}
      
    function hasSkill(skillId) {return true;}
    
  • 用对象展开操作符浅复制对象,优先于Object.assign 。使用对象剩余操作符来获得一个省略某些属性的新对象。

    // very bad
    const original = { a: 1, b: 2 };
    const copy = Object.assign(original, { c: 3 }); //  `original` 是可变的 ಠ_ಠ
    delete copy.a; // so does this
    // bad
    const original = { a: 1, b: 2 };
    const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
    // good
    const original = { a: 1, b: 2 };
    const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }
    const { a, ...noA } = copy; // noA => { b: 2, c: 3 }
    
  • 使用数组展开操作符 ... 复制数组。

    // bad
    const len = items.length;
    const itemsCopy = [];
    let i;
    for (i = 0; i < len; i += 1) {
    itemsCopy[i] = items[i];
    }
    // good
    const itemsCopy = [...items];
    
  • 使用展开操作符 ... 代替 Array.from,来将一个类数组(array-like) 对象转换成数组。

const foo = document.querySelectorAll('.foo');
// good
const nodes = Array.from(foo);
// best
const nodes = [...foo];

// bad
const baz = [...foo].map(bar);
// good
const baz = Array.from(foo, bar);
  • 当访问和使用对象的多个属性时,请使用对象解构.解构可以在你建这些属性的临时引用时,为你节省时间

    // bad
    function getFullName(user) {
    const firstName = user.firstName;
    const lastName = user.lastName;
    return `${firstName} ${lastName}`;
    }
    // good
    function getFullName(user) {
    const { firstName, lastName } = user;
    return `${firstName} ${lastName}`;
    }
    // best
    function getFullName({ firstName, lastName }) {
    return `${firstName} ${lastName}`;
    }
      
      
    const arr = [1, 2, 3, 4];
    // bad
    const first = arr[0];
    const second = arr[1];
    // good
    const [first, second] = arr;
    
  • 使用对象解构来实现多个返回值,而不是数组解构

    // bad
    function processInput(input) {
    // 那么奇迹发生了
    return [left, right, top, bottom];
    }
    // 调用者需要考虑返回数据的顺序
    const [left, __, top] = processInput(input);
    // good
    function processInput(input) {
    // 那么奇迹发生了
    return { left, right, top, bottom };
    }
    // 调用者只选择他们需要的数据
    const { left, top } = processInput(input);
    
  • 以编程方式构建字符串时,请使用模板字符串而不是字符串连接。 模板字符串为你提供了更好的可读性,简洁的语法,正确的换行符和字符串插值功能

    // bad
    function sayHi(name) {
    	return 'How are you, ' + name + '?';
    }
    // bad
    function sayHi(name) {
    	return ['How are you, ', name, '?'].join();
    }
    // bad
    function sayHi(name) {
    	return `How are you, ${ name }?`;
    }
    // good
    function sayHi(name) {
    	return `How are you, ${name}?`;
    }
    
  • 函数中,不要使用 arguments。可以选择 rest 语法 ... 替代。

    // bad
    function concatenateAll() {
    	const args = Array.prototype.slice.call(arguments);
    	return args.join('');
    }
    // good
    function concatenateAll(...args) {
    	return args.join('');
    }
    
  • 使用默认参数语法,而不要使用一个变化的函数参数。

    // really bad
    function handleThings(opts) {
        // 不!我们不应该改变函数参数。
        // 更加糟糕: 如果参数 opts 是 falsy(假值) 的话,它将被设置为一个对象,
        // 这可能是你想要的,但它可以引起一些小的错误。
        opts = opts || {};
        // ...
    }
    // still bad
    function handleThings(opts) {
    	if (opts === void 0) {
    		opts = {};
    	}
    	// ...
    }
    // good
    function handleThings(opts = {}) {
    	// ...
    }
    
  • 始终将默认参数放在最后。

      
    // bad
    function handleThings(opts = {}, name) {
    // ...
    }
    // good
    function handleThings(name, opts = {}) {
    // ...
    }
    
  • 优先使用展开运算符 ... 来调用可变参数函数。它更清洁,你不需要提供一个上下文,而且你不能轻易地实用 applynew

    // bad
    const x = [1, 2, 3, 4, 5];
    console.log.apply(console, x);
    // good
    const x = [1, 2, 3, 4, 5];
    console.log(...x);
    // bad
    new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
    // good
    new Date(...[2016, 8, 5]);
    
最近的文章

编程语言-C

翻译阶段 以实现定义方式,映射源文件的单独字节,为源字符集的字符。特别是以换行字符替代依赖OS的行尾指示符。以对应的单字节表示替换三标符。 删除行尾反斜杠和换行符 以空格字符替换注释;并分析语法。 执行预处理器。#include语句所引入的每个文件都经历上面4各过程,递归执行。此阶段结束,从源码移除所有预处理器指令。 将字符常量和字符串字面量所有字符及转义字符,从源字符集转换成执行字符集。 连接相邻的字符串字面量 编译。按照语法和语义分析记号,并将它们翻译成翻译单元。 链接...…

继续阅读
更早的文章

编程语言-C#

C#基础基本数据类型:byte,sbyte,short,ushort,int,uint,long,ulong,float,double,dcimal(128位十进制),bool,char,string;IntPtr,UIntPtr,object(所有类型的基类); delegate(匿名函数类型);复合数据类型:数组[], enum, struct ,class,interface流程控制语句:if..else, switch..case;while.., do..while,for,fo...…

继续阅读