關於對健壯性程式碼的理解

致愛麗絲發表於2020-06-06

這兩天學到了很多知識,對專案的嚴密性有了極為深刻的理解,簡而言之,身為前端開發者要站在使用者的角度去寫相關程式碼,而不能僅僅侷限於理所當然,也不可以認為資料有便有,沒有便沒有,身為開發者,更多的應該考慮使用者的感受,總結了以下幾點:

提高程式碼的健壯性

  1.非空過濾

給每一條要渲染顯示的資料新增過濾器

要思考的不僅僅是渲染成功後的結果,更多要思考的是如果渲染不成功會顯示什麼,也就是當返回結果為空時,要顯示給使用者的是什麼

  2. 不完全相信後臺

發起請求時新增條件判斷

雖然if/else飽受詬病,但可能後臺開發者本身也不能確保不出任何問題,為了提高容錯率,加一點條件判斷是必要的,並且,要結合多個條件確保拿到的是正確的資料

  3. 不完全相信使用者

對使用者輸入的資料進行嚴格驗證

作為開發者當然期待使用者輸入的是自己想要的格式,但使用者是單純的,你不能確保使用者一定會按照你想要的進行輸入,這一點至關重要

  4. 考慮程式碼的可複用性

包括html/css/js/單頁面元件

原則:抽離共性,保留不同

html: 若dom結構大致相同,可以使用相同的dom結構;
css/less/scss/stylus: 同一app內若有多次的div/view/text style,可以直接在public.css/less/sass/stylus中宣告共有樣式
js:將需要多次使用的業務邏輯封裝成單一功能函式,並在函式內部首先對引數格式進行評估,之後新增條件判斷對引數進行過濾篩選,最後再對符合條件的引數進行處理

如果單頁面中需要多次使用該函式,則僅需要對在script內進行封裝,如果在多頁面中需要多次使用該函式,可以建立一個utils.js檔案存放共有函式
(vue/uniapp)如果匯入utils.js的函式並準備在單頁面中進行使用時,推薦在該單頁面中宣告一個與utils.js中的同名函式,並直接return該同名函式(本質是為了返回utils.js中的同名函式)

  5.考慮網路請求

使用者的流量是寶貴的,後臺伺服器的壓力是可觀的

基於使用者場景(思考:使用者來到某一頁面的目的是什麼)選擇是否傳送適當的請求,要思考的是,如何在保證功能不變的情況下,減少與後臺的互動,從而節省頻寬

------------------------------------------------------------假裝是條分割線----------------------------------------------------------------------

精妙的過濾函式

1. 展示資料的非空處理

//用於過濾 undefined,空字串,null,'null'
filterEmpty(value,success,tips){
	  if(value === undefined || value === '' || value === null || value === 'null' || value === " "){
	    if(tips === undefined){
	      return "-";
	    }else{
	      return tips
	    }
	  }else{
	    if(typeof(success) === "function"){//如果是一個方法則呼叫方法
	      return success();
	    }else{//否則直接返回第一個引數
	      return value;
	    }
	  }
	}

2. 表單相關驗證

2.1 正則相關驗證

  //只包含數字,英文,漢字
  isNYC:function(obj ,tipValue,$this){
    let specialCharacters = /[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]/g;
    if(/[^a-zA-Z0-9\u4E00-\u9FA5]/.test(obj) && specialCharacters.test(obj)){
      let tip;
      if(tipValue !== undefined && tipValue !== '' && tipValue !== null && tipValue !== '' && tipValue !== " "){
        tip = tipValue;
      }else {
        tip = '名稱不能包含特殊字元';
      }
			uni.showToast({
				title:tip
			})
      return false;
    }
    return true;
  }

2.2 漢字驗證

 // 漢字
  isChinese: function(obj,$this) {
    var reg = /^[\u0391-\uFFE5]+$/;
    if(obj != "" && !reg.test(obj)) {
			uni.showToast({
				title:'必須輸入中文'
			})
      return false;
    }
    return true;
  }

2.3 字母

 // 字母
  checkChar: function(obj,$this) {
    var zmReg = /^[a-zA-Z]*$/;
    if(obj != "" && !zmReg.test(obj)) {
			uni.showToast({
				title:'只能是英文字母'
			})
      return false;
    }
    return true;
  }

2.4 數字

// 數字
  checkNumber: function(obj,$this) {
    var reg = /^[0-9]+$/;
    if(obj != "" && !reg.test(obj)) {
			uni.showToast({
				title:'只能輸入數字'
			})
      return false;
    }
    return true;
  }

2.5 英文字母和數字

  // 英文字母和數字
  checkStrOrNum: function(obj,$this) {
    var zmnumReg = /^[0-9a-zA-Z]*$/;
    if(obj != "" && !zmnumReg.test(obj)) {
			uni.showToast({
				title:'只能輸入是字母或者數字,請重新輸入'
			})
      return false;
    }
    return true;
  },

2.6 郵箱

  // 郵箱
  email: function(obj,$this) {
    var myreg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
    if(!myreg.test(obj)) {
			uni.showToast({
				title:'請輸入有效的郵箱'
			})
      return false;
    }
    return true;
  },

3 時間戳轉換

changeInfoDate(msesInt, format) {
  Date.prototype.Format = function(fmt) {
    var o = {
      "M+": this.getMonth() + 1, //月份
      "d+": this.getDate(), //日
      "H+": this.getHours(), //小時
      "m+": this.getMinutes(), //分
      "s+": this.getSeconds(), //秒
      "q+": Math.floor((this.getMonth() + 3) / 3), //季度
      "S": this.getMilliseconds() //毫秒
    };
    if(/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for(var k in o)
      if(new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
  };

  var dt = new Date(msesInt); // 初始化Date物件
  var ndt = dt.Format(format);
  return ndt;
};

filterDate(date,success,tips) {//用於過濾時間戳
  if(date === undefined || date === '' || date === null || date === 'null' || date == 0 || date === ' ' || date === " "){//判空處理
    if(tips == undefined){
      return "-";
    }else {
      return tips;
    }
  }else{
    if(typeof(date) === "number" || (typeof (date) === "string" && (date.length >= 10 && date.length <= 13) && date.indexOf("/") === -1 && date.indexOf("-") === -1 && date.indexOf("年") === -1 && date.indexOf(".") === -1)){//為時間戳
      if(typeof(date) === "string"){
        date = parseInt(date);
      }
      return changeInfoDate(date, 'yyyy-MM-dd');
    } else{
      if(typeof(success) === "function"){//如果是一個方法則呼叫方法
        return success();
      }else{//否則直接返回第一個引數
        return date;
      }
    }
  }
}

以上。

相關文章