1-JavaScript - 反射

为什么使用反射

声明:咱也不是专业前端,所以,理解的不对多多见谅,能解决实际问题就好。

反射的好处实在是太多了,比如通过反射机制能灵活构造一个类的对象,执行某个方法等;避免了硬编码等等。

举个例子,参照下图:

如果我选中一些用例,就可以做一些操作,可以执行用例和删除,他们分别对应不同的方法处理,怎么玩呢,我们可以为每个标签都绑定一个事件,然后点那个就触发哪个事件,或者使用事件委派:

<body>
    <ul class="dropdown-menu executeMenu" style="min-width: 79px;z-index: 1000">
        <li><a href="javascript:;" operation="executeCase">执行</a></li>
        <li><a href="javascript:;" operation="deleteCase">删除</a></li>
    </ul>
</body>
<script>
    $(".executeMenu").on('click', 'li a', function () {
		// 获取点击标签的 operation 属性值进行判断
        if ($(this).attr('operation') == 'executeCase') {
            // 执行对应的方法
            executeCase()
        }
        if ($(this).attr('operation') == 'deleteCase') {
            deleteCase()
        }
    });

    // 当点击操作按钮下面的执行标签
    function executeCase() {
        console.log('executeCase');
    }
    // 当点击操作按钮下面的删除标签
    function deleteCase() {
        console.log('deleteCase');
    }
</script>

PS:这里用的jQuery,谁让咱js菜的一笔.......

是的,这么用一点问题都没有,但是,后续如果再增加10个或更多操作项怎么办?难道再增加10个if判断。

那么,能不能这样:你添加操作项,就按照规则在标签内添加一个自定义属性operation,然后对应的实现一个同名的函数,就完事了。而不是如上面的示例中那样,还要在事件委派中在新增if语句。

这就用到了反射的思想,我们每次点击都能获取到对应的operation字符串形式的值,而我们在对应的实现了一个同名的函数,在事件委派的代码中自动反射执行对应的函数。

但是!很明显,一个是字符串一个是函数,它们的类型不一样,不作处理,永远不会等于。所以我们就想法设法让它能等于就好了。

首先,我们要能很简单获取到所有的函数:

<script>
    for (var prop in window) {
        // typeof(window[prop]): function
        console.log(prop, typeof(window[prop]))
    }
    // 等效于
    Object.keys(window).forEach(console.log);
</script>

它们在window对象中。

有了这些,我们就能使用反射了:

<script>

    $('.dropdown-menu').on('click', 'li a', function () {
        var operation = $(this).attr('operation');
        // window[operation]:函数对象
        // typeof(window[operation]):"function"
        if (typeof(window[operation]) == "function") {
            window[operation]()
        } else {
            // 否则就是没反射到
            console.log("未实现的方法: ", operation);
        }
    });
</script>

如果点击获取的operation值的类型在window对象中是函数类型。那么就执行这个函数即可。如果不是给一个简单的提示。

完整的示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>JavaScript反射机制</title>
</head>
<body>

<ul class="dropdown-menu" aria-labelledby="dLabel">
    <li><a href="javascript:;" operation="execute">执行</a></li>
    <li><a href="javascript:;" operation="del">删除</a></li>
    <li><a href="javascript:;" operation="edit">编辑</a></li>
    <li><a href="javascript:;" operation="add">添加</a></li>
    <li><a href="javascript:;" operation="export">导出</a></li>
</ul>
</body>
<!-- 首先引入 jQuery -->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

<script>

    $('.dropdown-menu').on('click', 'li a', function () {
        var operation = $(this).attr('operation');
        if (typeof(window[operation]) == "function") {
            window[operation]()
        } else {
            console.log("未实现的方法: ", operation);
        }
    });

    function add() {
        console.log('add operation')
    };

    function edit() {
        console.log('edit operation')
    };

    function del() {
        console.log('del operation')
    };

    function execute() {
        console.log('execute operation')
    };
</script>
</html>

欢迎斧正,that's all see also:[Javascript中的反射机制(五)](https://www.cnblogs.com/sunliyuan/p/5861828.html) | [JavaScript反射机制到底是什么?](https://segmentfault.com/q/1010000002761696) | [JAVA反射机制]()
posted @ 2019-09-18 17:53  听雨危楼  阅读(503)  评论(0编辑  收藏  举报