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反射机制](