1. 程式人生 > >在js中仿java的列舉型別設計例項

在js中仿java的列舉型別設計例項

簡介

在javascript中,像EventTarget.addEventListener()Document.createElement() 等方法,只接收指定字串作為引數。比如:
const okButton = document.getElementById("button_ok");
okButton.addEventListener('click', () => console.log('button_ok clicked!'), false);
在上述程式碼中,我們必須按Events 中所定義的型別字串(如:click, load)傳參,否則程式就不能正常工作。本文將介紹如何通過object
class兩種封裝形式,分別實現列舉型別。

object封裝

  • index.html
<!DOCTYPE>
<html>
<head>
    <meta charset="UTF-8">
    <title>enum</title>
</head>
<body>
<button id="button_cancel">Cancel</button>
<button id="button_ok">OK</button>
<script src="object_script.js"></script>
</body>
</html>
  • object_script.js
(function () {
    'use strict';

    /** 事件 */
    const Event = {
        CLICK: "click",
        LOAD: "load"
    };
    deepFreeze(Event);

    /** 響應 */
    const Response = {
        OK: {
            code: 100,
            message: "ok"
        },
        ERROR: {
            code: 900,
            message: "error"
        }
    };
    deepFreeze(Response);

    addEventListener(window, Event.LOAD, () => {
        const okButton = document.getElementById("button_ok");
        addEventListener(okButton, Event.CLICK, () => alert(generateResponseText(Response.OK)));
        const cancelButton = document.getElementById("button_cancel");
        addEventListener(cancelButton, Event.CLICK, () => alert(generateResponseText(Response.ERROR)));
    });

    /**
     * object深度凍結
     * @param {Object} object 物件
     */
    function deepFreeze(object) {
        Object.freeze(object);
        for (const key in object) {
            const value = object[key];
            if (!object.hasOwnProperty(key) || typeof value != "object" || Object.isFrozen(value)) {
                continue;
            }
            deepFreeze(value);
        }
    }

    /**
     * 事件監聽器登記
     * @param {EventTarget} target 目標
     * @param {String} event 事件
     * @param {Function} listener 監聽器
     * @throws {Error} 錯誤
     */
    function addEventListener(target, event, listener) {
        if (event === undefined) {
            throw new Error("event is undefined");
        }
        target.addEventListener(event, listener, false);
    }

    /**
     * 響應字串生成
     * @param {Object} response 響應
     * @return {String} 響應字串
     * @throws {Error} 錯誤
     */
    function generateResponseText(response) {
        if (response === undefined) {
            throw new Error("response is undefined");
        }
        return "[" + response.code + "] " + response.message;
    }
})();

class封裝

  • index_class.html
<!DOCTYPE>
<html>
<head>
    <meta charset="UTF-8">
    <title>enum</title>
</head>
<body>
<button id="button_cancel">Cancel</button>
<button id="button_ok">OK</button>
<script src="class_script.js"></script>
</body>
</html>
  • class_script.js
(function () {
    'use strict';

    /** 值儲存類 */
    class HasValue {
        /**
         * @param {Object} value 值
         */
        constructor(value) {
            this.value = value;
        }
    }

    /** 事件類 */
    class Event extends HasValue {
    }
    /** 事件常量 */
    const Events = {
        CLICK: new Event("click"),
        LOAD: new Event("load")
    };
    deepFreeze(Events);

    /** 響應類 */
    class Response {
        /**
         * @param {Number} code 編碼
         * @param {String} message 訊息
         */
        constructor(code, message) {
            this.code = code;
            this.message = message;
        }
    }
    /** 響應常量 */
    const Responses = {
        OK: new Response(100, "ok"),
        ERROR: new Response(900, "error")
    };
    deepFreeze(Responses);

    addEventListener(window, Events.LOAD, () => {
        const okButton = document.getElementById("button_ok");
        addEventListener(okButton, Events.CLICK, () => alert(generateResponseText(Responses.OK)));
        const cancelButton = document.getElementById("button_cancel");
        addEventListener(cancelButton, Events.CLICK, () => alert(generateResponseText(Responses.ERROR)));
    });

    /**
     * object深度凍結
     * @param {Object} object 物件
     */
    function deepFreeze(object) {
        Object.freeze(object);
        for (const key in object) {
            const value = object[key];
            if (!object.hasOwnProperty(key) || typeof value != "object" || Object.isFrozen(value)) {
                continue;
            }
            deepFreeze(value);
        }
    }

    /**
     * 事件監聽器登記
     * @param {EventTarget} target 目標
     * @param {Event} event 事件例項
     * @param {Function} listener 監聽器
     * @throws {Error} 錯誤
     */
    function addEventListener(target, event, listener) {
        if (!(event instanceof Event)) {
            throw new Error("event is not instance of Event");
        }
        target.addEventListener(event.value, listener, false);
    }

    /**
     * 響應字串生成
     * @param {Object} response 響應
     * @return {String} 響應字串
     * @throws {Error} 錯誤
     */
    function generateResponseText(response) {
        if (!(response instanceof Response)) {
            throw new Error("response is not instance of Response");
        }
        return "[" + response.code + "] " + response.message;
    }
})();


檢視原文:https://www.huuinn.com/archives/424
更多技術乾貨:風勻坊
關注公眾號:風勻坊