一个JS小技巧
来源:互联网 发布:美版a1453支持什么网络 编辑:程序博客网 时间:2024/05/16 20:28
我们在开发中通常会遇到这样一种情况,比如我有一个函数
这个函数有个参数,函数的功能就是打印参数中name属性
function showName(obj){ alert(obj.name);}// 调用var Tom = {name:"Tom"};showName(Tom); // Tom
此时我有一个需求,需要动态生成一些按钮,点击按钮打印不同人的名字
<html><head><title></title><script type="text/javascript"><!--function showName(obj){alert(obj.name);}window.onload = function(){var Jim = {name:"Jim"};var Lucy = {name:"Lucy"};var buttons = '<input type="button" value="点击" onclick="showName(Jim)">' +'<input type="button" value="点击" onclick="showName(Lucy)">';document.body.innerHTML += buttons;}//--></script></head><body></body></html>
此时点击按钮会报错,因为Jim,Lucy是局部对象,按钮上的showName()函数访问不到,一种解决方法是把他们放到onload函数外面,成为全局对象.
显然这不是一种好方法.那么我们能不能用一个工具辅助下来实现呢
直接上代码吧
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><script type="text/javascript"><!--var FunUtil = (function(){var index = 0;var handlerStore = []; // 存放方法句柄var paramStore = []; // 存放参数return {// 创建方法字符串// scope:作用域// methodName:方法名,字符串格式// param:参数createFun:function(scope,methodName,param){var currentIndex = index++; // 创建索引// 根据索引储存方法句柄和方法参数handlerStore[currentIndex] = function(param){ scope[methodName](param)};paramStore[currentIndex] = param;return 'FunUtil._runFun('+currentIndex+')';}// 执行方法// index:索引.根据这个索引找到方法句柄和方法参数,_runFun:function(index){var handler = handlerStore[index];var param = paramStore[index];handler(param);}};})();function showName(obj){alert(obj.name);}window.onload = function(){var Jim = {name:"Jim"};var Lucy = {name:"Lucy"};var buttons = '<input type="button" value="点击" onclick="showName(Jim)">' +'<input type="button" value="点击" onclick="showName(Lucy)">' // 使用工具 +'<input type="button" value="使用工具" onclick="'+FunUtil.createFun(window,'showName',Jim)+'">' +'<input type="button" value="使用工具" onclick="'+FunUtil.createFun(window,'showName',Lucy)+'">';document.body.innerHTML += buttons;}//--></script></head><body></body></html>
这里我写了一个工具类FunUtil,我们就使用它的一个方法
FunUtil.createFun(scope,methodName,param);
第一个参数是被调用函数的作用域,这里就是window
第二个参数是函数名字,字符串形式,这里就是''showName''
第三个参数是函数参数,这里是Jim,Lucy对象
----------------------------------
再来说下它的实现原理:
用两个数组分别来保存函数句柄和参数,然后我们通过数组的索引来获取对应的函数句柄和参数
注释已经写的很清楚了.
----------------------------------
当我写好这个工具的时候发现它并不完美,如果我们要传入多个参数呢
当时脑海中就想到了fun.apply(scope,arr);关于此方法可以网上搜索javascript的call apply
于是就有了下面的改进版
[推荐]
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><script type="text/javascript"><!--/* 使用方法: FunUtil.createFun(scope,'some_mothod_name',obj1); FunUtil.createFun(scope,'some_mothod_name',obj1,obj2); ...*/var FunUtil = (function(){var index = 0; var handlerStore = []; // 存放方法句柄return {// scope:作用域// methodName:方法名,字符串格式// ...:参数可放多个createFun:function(scope,methodName){var currentIndex = index++; // 创建索引var argu = []; // 用来存放多个参数// 构建参数for(var i=2,len=arguments.length;i<len;i++){argu.push(arguments[i]);}// 把函数句柄存在数组里handlerStore[currentIndex] = (function(scope,methodName,argu){// 生成函数调用句柄return function(){scope[methodName].apply(scope,argu);}}(scope,methodName,argu));return 'FunUtil._runFun('+currentIndex+')';}// 执行方法// index:索引.根据这个索引找到执行函数,_runFun:function(index){var handler = handlerStore[index];handler();// 该函数已经传入了参数}};})();function showName(obj1,obj2){alert(obj1.name + " and " + obj2.name);}window.onload = function(){var Jim = {name:"Jim"};var Lucy = {name:"Lucy"};var aa = {name:'aa'};var bb = {name:'bb'};var buttons = '<input type="button" value="点击" onclick="showName(Jim)">' +'<input type="button" value="点击" onclick="showName(Lucy)">' // 使用工具,传入多个参数 +'<input type="button" value="使用工具" onclick="'+FunUtil.createFun(window,'showName',Jim,Lucy)+'">' +'<input type="button" value="使用工具" onclick="'+FunUtil.createFun(window,'showName',aa,bb)+'">' ;document.body.innerHTML += buttons;}//--></script></head><body></body></html>
要说明的都写在注释里面了,核心方法就是scope[methodName].apply(scope,argu);
可能这个例子有点简单了,我们再来一个复杂点的,更贴近于实际项目的例子
我这里有个表格控件Grid,我要实现一个修改功能,在页面上生成修改列,点击修改,就可修改信息
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><script type="text/javascript">var FunUtil = (function(){var index = 0; var handlerStore = []; // 存放方法句柄return {// scope:作用域// methodName:方法名,字符串格式// ...:参数可放多个createFun:function(scope,methodName){var currentIndex = index++; // 创建索引var argu = []; // 用来存放多个参数// 构建参数for(var i=2,len=arguments.length;i<len;i++){argu.push(arguments[i]);}// 把函数句柄存在数组里handlerStore[currentIndex] = (function(scope,methodName,argu){// 生成函数调用句柄return function(){scope[methodName].apply(scope,argu);}}(scope,methodName,argu));return 'FunUtil._runFun('+currentIndex+')';}// 执行方法// index:索引.根据这个索引找到执行函数,_runFun:function(index){var handler = handlerStore[index];handler();// 该函数已经传入了参数}};})();var Grid = function(){this.row = [{id:1,name:'Jack'},{id:2,name:'Tom'},{id:3,name:'Lucy'}];}Grid.prototype.updateData = function(obj){// 修改信息,可以跳转到另一个页面或者弹窗alert('修改:'+obj.name+',主键ID:'+obj.id);}Grid.prototype.sendToBody = function(){var html = '';for(var i in this.row){var obj = this.row[i];html += (obj.id + ' ' + obj.name + ' <a href="javascript:void(0)" onclick="'+FunUtil.createFun(this,'updateData',obj)+'">修改</a><br>');}document.body.innerHTML += html;}window.onload = function(){var grid = new Grid();grid.sendToBody();}</script></head><body> </body></html>
这样,一个简单的表格就生成了
FunUtil.createFun(this,'updateData',obj); 这里的this指的是Grid对象,整句话的意思就是调用Grid的'updateData'方法,并传入obj
- 一个JS小技巧
- 在js里一个小技巧
- JS日期比较的一个小技巧
- js小技巧:如何删去js数组中的一个值
- js中的小技巧
- js经验总结,小技巧
- js小技巧
- js小技巧
- js 小技巧
- js小技巧
- js使用小技巧
- js实用小技巧
- JS小技巧
- JS小技巧
- js小技巧 (一)
- js中的小技巧
- JS小技巧总汇
- js中的小技巧
- This Android SDK requires Android Developer Toolkit version 20.0.0 or above错误问题解决
- Linux CPU数量判断
- 面试题,使用流的方式复制文件
- IF语句大显身手之成绩判断
- Maven安装全程指南
- 一个JS小技巧
- Android使用APIDemos代码(EditText左右抖动)
- NYOJ-35 表达式求值
- C程序设计WEEK7晚上练习
- java 中如何设置可被所有类访问的全局变量
- ifconfig用法详解
- 高斯列主消元详解及模板
- 女子墓地捉鬼被吓病 公益性墓地大多违规“偷着卖”
- 第6周作业1-闰年之循环判断(网络131 梁文俊)