讀書筆記(02) - 可維護性 - JavaScript高級程序設計

coding

編寫可維護性代碼

可維護的代碼遵循原則:

  1. 可理解性 (方便他人理解)
  2. 直觀性 (一眼明瞭)
  3. 可適應性 (數據變化無需重寫方法)
  4. 可擴展性 (應對未來需求擴展,要求較高)
  5. 可調試性 (錯誤處理方便定位)

命名方式

變量取名多爲爲名詞,方法取名多爲爲動詞

// 變量名
car, person;

// 方法名
getName, isEnable;

解耦

功能過於依賴,代碼耦合過緊,不利於維護。而通過解耦能讓我們更專一地處理特定功能業務的開發,也方便我們開發中調試,從複雜的耦合依賴中抽離出來。

解耦優勢:代碼複用,單元測試。

解耦原則:

  1. HTML/JavaScript解耦(結構層/行爲層的解耦)
  2. CSS/JavaScript解耦 (樣式層/行爲層的解耦)
  3. 應用邏輯/事件處理程序解耦

應用邏輯/事件處理程序解耦合的原則:

  1. 勿將event對象傳給其他方法;只傳來自event對象中所> 需的數據
  2. 任何可以在應用層面的動作都應該可以在不執行任何事> 件處理程序的情況下進行;
  3. 任何事件處理程序都應該處理事件,然後將處理轉交給應用邏輯
// 一個事件解耦的例子
var pwdInput = document.getElementById('password');

// 回車事件
pwdInput.addEventListener('keyup', function(event){
    if (event.keyCode == 13) {
        validatePassword(event.target.value);
    }
})

// 失焦事件
pwdInput.addEventListener('blur', function(event) {
    validatePassword(event.target.value);
})

// 業務應用單獨封裝到一個方法裏面,多處複用/單元測試皆可
function validatePassword(pwd) {
    if (!pwd) {
        alert('密碼不能爲空!');
    } 
}

對象所有權

JavaScript中是通過原型鏈來實現繼承,而原型繼承的一個特點就是原型上定義的屬性方法,可以被多個實例共享使用。

對象維護原則:

  1. 不要爲實例或原型添加屬性
  2. 不要爲實例或原型添加方法
  3. 不要重定義已存在的方法

需要修改對象時:

  1. 創建包含所需功能的新對象,並用它與相關對象進行交互
  2. 創建自定義類型,繼承需要進行修改的類型,然後可以自定義類型添加額外功能

全局變量引申命名空間

var name = 'KenTsang';
function sayName () {
    console.log(name);
}

var MyApp = {
    name: 'KenTsang',
    sayName: function() {
        console.log(this.name);
    }
    skill: {
        html: 80,
        css: 80,
        js: 80
    }
}

MyApp.skill.js // 80

雖然減少程序員輸錯代碼造成修改全局變量的機率,但依舊可以修改到全局變量,而且增加了代碼量。

常用null比較誤區

TIPS: null可同時判斷null/undefined,可用來判斷對象屬性是否存在。

使用null作判斷無法進行充分的類型檢查。

// 錯誤用法
function sortArrays(values) {
    if (values != null) {
        // 非數組類型就會報錯,因爲sort方法只有Array才具備
        values.sort();
    }
} 

// 正確用法
if (values instanceof Array) {
    value.sort();
}

使用null比較的代碼,替換原則:

  1. 如果值應爲一個引用類型,使用instanceof操作符檢查其構造函數
  2. 如果值應爲一個基本類型(值類型),使用typeof檢查其類型
  3. 如果是希望對象包含某個特點的方法名,則使用typeof操作符確保指定名字的方法存在於對象上
// 值類型 (Number, String, Boolean)
typeof value == 'string';

// 引用類型 (Array, Object, Function)
value instanceof Array;

// 對象方法 (Object.property)
typeof person.getName == 'function'

常量應用

var CONSTANS = {
    INVALID_VALUES_MSG: "Invalid value!",
    INVALID_VALUE_URL: "/erros/invalid.php"
}

CONSTANS.INVALID_VALUES_MSG // "Invalid value!"

常量應用原則:

  1. 重複值——多處地方引用的值 (CSS類名/後端返回的狀態碼)。
  2. 用戶界面字符串——顯示給用戶的字符串 (國際化, 替換爲對應的語言包文件)
  3. URLs——公共地方存放所有的URL (測試API的URL/上線API的URL)
  4. 任何可能會更改的值 (通常是環境/語言配置上的修改)

redux/vuex的actionType判斷的應用,也是常量應用常見的場景。好處就是引用時拼寫錯誤會直接拋出變量引用錯誤,而直接用字符串值判斷,則不會拋出錯誤,不利於調試。

// redux-reducer.js文件中應用常量
import {
    ADD_TODO_ITEM, 
    DELETE_TODO_ITEM
} from './actionTypes'

const defaultState = {
    inputValue: '',
    list: []
};

export default (state = defaultState, action) => {
    let newState = JSON.parse(JSON.stringify(state));

    switch (action.type) {
        case DELETE_TODO_ITEM:
            newState.list.splice(action.value, 1);
        break;
        case ADD_TODO_ITEM:
            if (newState.inputValue.trim().length) {
                newState.list.push(newState.inputValue);
            }
            newState.inputValue = '';
        break;
    }

    return newState;
}

參考文檔

作者:以樂之名
本文原創,有不當的地方歡迎指出。轉載請指明出處。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章