目录

JavaScript数据交互规范

JavaScript格式规范

JavaScript注释规范

javascript语言规范


此文参考 Denson / 微信小程序开发规范文档

JavaScript数据交互规范

网络请求(wx.request)

1. loading提示优化

    loading提示能让用户知道当前的操作进度,合理地显示loading提示,有助于提升产品气质和用户体验。

通常我们认为,发起请求即显示loading提示,请求完成隐藏loading提示。用户所处的网络环境较差时,loading提示会正常显示隐藏,用户所处网络环境良好时,loading提示会闪一下。大多时候用户所处的网络环境都是良好的,网络请求能即时返回结果,此时就没必要显示loading提示,也可以避免那尴尬的一闪。

   团队约定

   网络请求在800毫秒内返回了结果,不显示loading提示,超过800毫秒还未返回结果开始显示loading提示。

   实现思路

   在请求之前声明一个变量loadingStatus来控制loading提示何时显示。loadingStatus有以下两个值,分别代表二个状态:


状态说明

是否显示loading提示

1

初始值

显示

0

请求完成

不显示

let loadingStatus = 0;

   在请求之前放置一枚定时器,这个定时器在800毫秒之后执行,在其内控制是否显示loading提示。

/* 
* 定时器在800毫秒后执行时,会判断loadingStatus状态,
* 如果loadingStatus还是初始值1(没有被改变过),就显示loading提示。
* 如果loadingStatus不是1,说明网络请求已返回(此时loadingStatus的值应该是0)。
*/
setTimeout(() => {
  if (loadingStatus === 1) {
    wx.showLoading({
      title: '加载中...'
    })
  }
}, 800);

   在wx.request参数的complete里改变loadingStatus的值

wx.request({
    ...
    complete: function () {
        // 请求完成,改变loadingSataus的值
        loadingSataus = 0;
    }  
})

   完整流程

...
  getUserInfo: function () {
    // 其它代码...
    let loadingStatus = 1;
    setTimeout(() => {
      if (loadingStatus === 1) {
        wx.showLoading({
          title: '加载中...'
        })
      }
    }, 800)
    // 开始请求
    wx.request({
      url: 'your api url',
      method: 'GET',
      data: {
        userid: 123456
      },
      success: function (res) {
        // 处理返回结果
      },
      fail: function () {
        // 处理失败 
      },
      complete: function () {
        // 请求完成,关掉loading,改变loadingSataus的值
        wx.hideLoading();
        loadingSataus = 0;
      }
    })

  },
  ...

2. 限制重复请求

   我们的程序里有很多个请求,某个网络请求在未完成的情况下,该请求不应该再被发起,必须加以限制,保证业务流程有序进行。尽管     有些限制在后端处理了,但前端也必须加以限制,把隐患扼杀在摇篮。

连续的重复请求不加限制,会让前端程序数据错乱(如列表类数据加载),也会给后端造成不必要性能的负担,甚至引起数据库数据错乱。如:签到,领取积分,点赞(听说手快能多点几个)。

 

   实现思路

   在全局声明一个requestStatus用来控制请求是否能再次发起。


状态说明

是否允许发起请求

-1

初始值,请求从未发起过

允许

0

正在请求中

不允许

1

请求完成

允许

onLoad: function () {
    /*
     * 当requestStatus为-1或1时可以再次发起网络请求,为0时不可发起。
     */ 
    this.requestStatus = -1;
  }

   在发起请求之前通过requestStatus判断是否能发起请求。

// requestStatus值为0,表明已经有一个当前的请求在执行,不能再次发起请求,中断操作。
if(that.requestStatus === 0) {
  return;
}
// 如果可以发起请求,发起之前把requestStatus值改为0
this.requestStatus = 0;

   请求完成,在wx.request参数的complete里改变requestStatus的值

// 其它代码...
complete: function () {
  // 把requestStatus的值改为1
  this.requestStatus = 1;
}

   完整流程

...
  onLoad: function () {
    this.requestStatus = -1;
  }
  ...
  getUserInfo:()=> {
    // 进入请求之前,检查是否可以发起网络请求
    if(this.requestStatus === 0) {
      return;
    }
    // 如果可以请求,就把requestStatus的值改成0
    this.requestStatus = 0;
    // 开始请求
    wx.request({
      url: 'your api url',
      method: 'GET',
      data: {
        userid: 123456
      },
      success: function (res) {
        // 请求成功的代码
      },
      fail: function () {
       // 请求失败的代码
      },
      complete: function () {
        this.requestStatus = 1;
      }
    })
  },
  ...

3. 请求错误处理

   不管网络请求返回错误error还是请求失败fail,都应该反馈给用户。

部分开者开发过程中处理网络请求结果时,只处理请求成功返回成功的结果,而对返回错误和请求失败没做处理,这是不科学的。(数据没有请求成功,又不给用户对应的错误反馈,用户会一脸懵比的。)

   团队约定

   为了方便开者准确定位错误和更舒适的用户体验,每个网络请求必须处理请返回错误error和请求失败fail,并适当地反馈给用户。

  wx.request参数的fail方法必须写法。

getUserInfo: function () {
  ...
  wx.request({
    url: 'your api url',
    method: 'GET',
    data: {
      userid: userid + ''
    },
    success: function (res) {
      if (res.data.code === 200) {
        // 请求成功,返回成功
        // ...
      } else {
        // 请求成功,返回错误
        wx.showToast({
          title: '数据返回错误',
          image: '/images/toast_warning.png',
          duration: 1000
        })
      }
    },
    fail: function () {
      // 请求失败 
      wx.showToast({
        title: '请求失败',
        image: '/images/toast_warning.png',
        duration: 1000
      })
    },
    complete: function () {
      // 不管是请求成功还是失败
    }
})

},

ps:

Page参数内的方法声明顺序

使用微信开发者工具新建一个Page时,在.jsPage函数的参数内自带了一些属性和方法,自定义方法放在这些方法后面。

 

JavaScript格式规范

前奏

约定JavaScript使用ES6标准开发

wxs(WeiXin Script)和JavaScript是不同的语言,有自己的语法,wxs请参考wxs文档,这里的规范仅针对js。

变量命名

   关于变量命名,主流分为驼峰式命名和下划线式命名两大阵营。我们约定,统一使用驼峰式命名。

  • 推荐写法
•  let userId = 654321; 
function getUserInfo () {
  ....
}
• 不推荐写法 let user_id = 654321; 
function get_user_info () {
  ....
}

分号

   尽管现在JavaScript引擎知道该在什么情况下自动添加分号,由于项目历史原因和避免代码压缩时产生不必要的问题,我们约定使用分号。分号紧跟代码的最后一个字符。

  • 推荐写法 let loading = -1;
  • 不推荐写法 let loading = -1 ;

逗号

   逗号分割列表时,逗号放置在当前行的末尾。

  • 推荐写法
•  let bar = 1, 
    foo = 2;
  • 不推荐写法
• let bar = 1 
    , foo = 2;

   数组(或对象)的最后一个元素(或属性)后面的逗号是拖尾逗号,示例:


let o = {
   a: 1,
   b: 2, // 拖尾逗号
 }


   对于数组和对象,最后一个元素或属性与右括号]}不在同一行时,可以(但不要求)使用拖尾逗号;在同一行时,禁止使用拖尾逗号。

  • 推荐写法
• let arr = ['name',
  'age',
  'gender',
]
let o1 = {a: 1,b: 2};
let o2 = {
  a: 1,
  b: 2,
};
• 错误写法 let arr = ['name','age','gender',]
let o1 = {a: 1,b: 2,}

   同一行内代码用到逗号,逗号后面加一个空格字符,提高代码可读性。

  • 推荐写法
•  let bar = 1, foo = 2;
let arr = [1, 2, 3, 4, 5];
  • 不推荐写法
•  let bar = 1,foo = 2;
let arr = [1,2,3,4,5]

缩进

   统一使用2个空格字符进行代码缩进。

   操作符前后加一个空格字符。

  • 推荐写法 let a = 1 + 2;
  • 不推荐写法 let a = 1+2;

函数

   函数声明式声明函数时,函数名与参数括号()连在一起,之间不加空格;参数括号()与函数体的左大括号{之间一个空格字符。

  • 推荐写法
•  function getInfo(userId) {
  ...
}
  • 不推荐写法
function getInfo1 (userId) {
  ...
}
• function getInfo2(userId){
  ...
}

   函数字面量里,关键字function与参数括号()之间一个空格字符,参数括号()与函数体的左大括号{之间一个空格字符。

  • 推荐写法
• let getInfo = function (userId) {
  ...
}
  • 不推荐写法
let getInfo1 = function(userId) {
  ...
}
• let getInfo2 = function(userId){
  ...
}

   函数调用时,禁止有空格。

  • 推荐写法 getInfo();
  • 错误写法 getInfo ();

对象字面量

   对象字面量的属性名和冒号:之间不能有空格字符,冒号:和属性值之间一个空格字符。

  • 推荐写法
•  let o1 = { a: 1, b: 2, c: 3 }
let o2 = {
    e: 5,
    f: 6,
    g: 7,
}
  • 不推荐写法
•  let o1 = { a:1, b :2, c : 3}
let o2 = {
    e:5,
    f :6,
    g : 7,
}

   对象字面量在一行内时,左括号{和右括号}与代码各间隔一个空格字符。

  • 推荐写法 let o1 = { a: 1, b: 2, c: 3 }
  • 不推荐写法 let o1 = {a: 1, b: 2, c: 3}

单行代码

   在单行代码中使用空格。

  • 推荐写法
• function foo() { return true }
if (true) { return true }
  • 不推荐写法
•  function foo(){return true}
if(true){return true}

代码块

   大括号{}包裹起来的代码叫代码块,示例:


{
  let userId = 654321;
}


   代码块前统一加一个空格字符

  • 推荐写法
•  if (true) {
  return '成功!' 
}

function getInfo() {
  ...
}
  • 不推荐写法
•  if (true){
  return '成功!' 
}

function getInfo(){
  ...
}

计算属性

   在对象的计算属性内,禁止有空格。

  • 推荐写法 obj['name']
  • 不推荐写法 obj['name' ] obj[ 'name']

空行

   空行对分离代码逻辑有帮助,但过多的空行会占据太多的屏幕空间,影响代码可读性。我们约定,最大连续空行数为2。

  • 推荐写法
•  if(true) {
  console.log('成功!');
}

function getUserInfo () {
  ...
}
  • 不推荐写法
if(true) {
  console.log('成功!');
}
• 
function getUserInfo () {
  ...
}

   在非空文件中,拖尾空行可以减少版本控制时的代码冲突。

  • 推荐写法

function getUserInfo () { ... } // ↑上面一行是空行

  • 不推荐写法

function getUserInfo () { ... }

大括号{}风格

用来描述大括号{}与代码块相对位置的方法很多,如下:

我们约定,使用风格一。

  • 风格一
•  if (true) {
  console.log('true');  
} else {
  console.log('false');
}
  • 风格二
• if (true) {
  console.log('true');  
} 
else {
  console.log('false');
}
  • 风格三
•  if (true) 
{
  console.log('true');  
}
else
{
  console.log('false');
}

我们约定,使用风格一。

JavaScript注释规范

注释

   注释分为单行注释和多行注释。

   单行注释以//开头。

   多行注释以/*开始,以*/结束。


/* * 多行注释 * 示例 */


团队约定

单行注释

   一般用于简单的描述,如状态描述,属性描述等。书写时应遵循以下规范:

  • 注释符号//与注释内容之间一个空格字符
  • 注释位于注释代码上面
  • 单独占一行

   示例

  • 推荐写法: // 初始化 let statusCode = -1;
  • 不推荐写法: let statusCode = -1; // 初始化

多行注释

   一般用于描述某一块代码的功能,逻辑思路,或参数说明等。书写时应该遵循以下规范

  • 注释开始符号/*和结束符号*/各占一行
  • 结束符号*/前面加一个空格字符
  • 代码块与代码块之间相隔一行

   示例

  • 推荐写法: /* * 多行注释 * 多行注释 * 多行注释 */
  • 不推荐写法: /* 多行注释 * 多行注释 * 多行注释 * 多行注释 */ /* 多行注释多行注释 */

文件注释

   文件注释位于文件的最前面,主要是对当前这个文件的代码做个整体说明或注意的事项

   示例

  • 推荐写法:
•  /*!
 * jRaiser 2 Javascript Library
 * sizzle - v1.9.1 (2013-03-15T10:07:24+0800)
 * http://jraiser.org/ | Released under MIT license
 *
 * Include sizzle (http://sizzlejs.com/)
 */

javascript语言规范

前奏

约定JavaScript使用ES6标准开发

wxs(WeiXin Script)和JavaScript是不同的语言,有自己的语法,wxs请参考wxs文档,这里的规范仅针对js。

关键字

   任何时候,避免使用语言保留关键字命名。

变量声明

   使用let代替var声明变量,


let loadding = -1;
 loadding = 0;


   使用const声明常量,常量名要求大写,多个词之间以下划线_连接。


const { HOST, GET_URL } = require("../../utils/api.js");


   js允许一个声明可以有多个变量。我们约定,一个声明只有一个变量。

  • 推荐写法
•  let a = 0; 
let b = 1;
let c = 2;
  • 不推荐写法
•  let a = 0, b = 1, c = 2;

字符串

   字符串统一使用单引号'',不使用双引号""


let title = '标题标题标题标题标题标题标题';


   字符串需要换行或由代码生成的字符串时使用模板字符串 ``

  • 推荐写法 // 字符串换行 let content = `文本文本文本文本文本文本文本文本文本`; // 代码拼接生成字符串 let editor = '编辑内容'; let text = `本文本文本文本文本文${editor}`;
  • 不推荐写法 // 字符串换行,使用 \n let content = '文本文本文本文本文本文本文本文本文本、 \n 文本文本文本文本文本 \n文本文本文本。'; // 代码拼接生成字符串 let editor = '编辑内容'; let text = '本文本文本文本文本文' + editor;

函数

   使用箭头函数。箭头函数不仅简洁,还可以保留this指向


[1,2,3].map((item, index) => {
   let res = item + index;
   return res + 1;
 });


   函数只有一个参数时,参数的()省略:


let show = a => {
    alert(a*2);
 }


   函数体只有一个return语句时,函数体的{}省略:


let show = (a,b) => a+b;


数组

   使用字面量创建数组


let arr = [];


   使用新方法forEach,map,filter,reduce处理数组数据,代码书写更简洁

• 推荐写法 // 取出数组里的偶数
let arr = [1,2,3,4,5,6,7,8];
let result = arr.filter(item=>item%2===0)
// 输出:[2, 4, 6, 8]
• 不推荐写法 // 取出数组里的偶数
let arr = [1,2,3,4,5,6,7,8];
let result = [];
for(let i=0; i<arr.length; i++) {
  let item = arr[i];
  if(item%2===0) {
      result.push(item)
  }
}
// 输出:[2, 4, 6, 8]

使用解构赋值和扩展运算符...简化代码

对象

使用字面量值创建函数


let obj = {};


属性简写,属性名跟值的变量(key和value)一样时,只写属性名

  • 推荐写法
•  let a = 5;
let obj = {
  a,
  b: 12
}
  • 不推荐写法
•  let a = 5;
let obj = {
  a:a
  b: 12
}

方法简写,不写function:

  • 推荐写法
•  let obj = {
  a:13,
  show(){
    console.log(this.a);
  }
}
  • 不推荐写法
•  let obj = {
a: 13,
  show: function(){
    console.log(this.a);
  }
}

this

用到this转换的地方,统一使用that


let that = this;