关于回调函数指定参数问题,由来已久,extjs简洁优雅完美的解决了这个问题,今天来学习一下(不推荐 createCallback )
createDelegate ( [Object obj ] , [Array args ] , [Boolean/Number appendArgs ] ) : Function
返回一个函数, 这个函数调用原函数,原函数中的this指向obj ,关于这个函数的参数由 appendArgs 指定 :
如 function2=function1.createDelegate(obj,args,appendArgs);
function2 call function1 ,function1 中的 this == obj
1. appendArgs falsy
那么 调用
function2时传的参数被忽略,args数组参数作为function1的参数运行。
2. appendArgs === true
那么
调用
function2时传的参数放在args数组前面合成一个新的数组,作为function1的参数运行。
3.typeof appendArgs == 'Number'
假设 调用 function2时传的参数 为 array1 (注意要 slice 为 真正的 Array)
那么将 args 数组插入到 array1 的指定 appendArgs位置 (利用 splice( appendArgs,0 ))
然后再把最终数组 作为function1的参数运行。
示例使用代码:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
- <head>
- <title>createDelegate测试</title>
- <script type="text/javascript" src="javascript/ext-base.js"></script>
- <script type="text/javascript" src="javascript/ext-core.js"></script>
- <script type="text/javascript">
- //<![CDATA[
- Ext.onReady(function() {
- function action_ba(info) {
- alert(this.dom.innerHTML);
- alert(info);
- }
- function action_bb(e,this_,o,info) {
- alert(this.dom.innerHTML);
- alert(e.type+' '+info);
- }
- function action_bc(info,e) {
- alert(this.dom.innerHTML);
- alert(info +' '+e.type);
- }
- Ext.get('action_a').on('click',action_ba.createDelegate(Ext.get('action_a'),['自定义参数覆盖event系列参数']));
- Ext.get('action_b').on('click',action_bb.createDelegate(Ext.get('action_b'),['自定义参数在最后'],true));
- Ext.get('action_c').on('click',action_bc.createDelegate(Ext.get('action_c'),['自定义参数在第一位'],0));
- });
- //]]>
- </script>
- </head>
- <body>
- <button id='action_a'> 测试覆盖参数</button>
- <button id='action_b'> 测试添加参数</button>
- <button id='action_c'> 测试插入参数</button>
- </body>
- </html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>createDelegate测试</title>
<script type="text/javascript" src="javascript/ext-base.js"></script>
<script type="text/javascript" src="javascript/ext-core.js"></script>
<script type="text/javascript">
//<![CDATA[
Ext.onReady(function() {
function action_ba(info) {
alert(this.dom.innerHTML);
alert(info);
}
function action_bb(e,this_,o,info) {
alert(this.dom.innerHTML);
alert(e.type+' '+info);
}
function action_bc(info,e) {
alert(this.dom.innerHTML);
alert(info +' '+e.type);
}
Ext.get('action_a').on('click',action_ba.createDelegate(Ext.get('action_a'),['自定义参数覆盖event系列参数']));
Ext.get('action_b').on('click',action_bb.createDelegate(Ext.get('action_b'),['自定义参数在最后'],true));
Ext.get('action_c').on('click',action_bc.createDelegate(Ext.get('action_c'),['自定义参数在第一位'],0));
});
//]]>
</script>
</head>
<body>
<button id='action_a'> 测试覆盖参数</button>
<button id='action_b'> 测试添加参数</button>
<button id='action_c'> 测试插入参数</button>
</body>
</html>
附录:Extjs 实现代码
- Function.prototype.createDelegate = function(obj, args, appendArgs){
- var method = this;
- return function() {
- var callArgs = args || arguments;
- if(appendArgs === true){
- callArgs = Array.prototype.slice.call(arguments, 0);
- callArgs = callArgs.concat(args);
- }else if(typeof appendArgs == "number"){
- callArgs = Array.prototype.slice.call(arguments, 0);
- // copy arguments first
- var applyArgs = [appendArgs, 0].concat(args);
- // create method call params
- Array.prototype.splice.apply(callArgs, applyArgs);
- // splice them in
- }
- return method.apply(obj || window, callArgs);
- };
- }
Function.prototype.createDelegate = function(obj, args, appendArgs){ var method = this; return function() { var callArgs = args || arguments; if(appendArgs === true){ callArgs = Array.prototype.slice.call(arguments, 0); callArgs = callArgs.concat(args); }else if(typeof appendArgs == "number"){ callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first var applyArgs = [appendArgs, 0].concat(args); // create method call params Array.prototype.splice.apply(callArgs, applyArgs); // splice them in } return method.apply(obj || window, callArgs); }; }