关于回调函数指定参数问题,由来已久,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);
-
-
var applyArgs = [appendArgs, 0].concat(args);
-
- Array.prototype.splice.apply(callArgs, applyArgs);
-
- }
-
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);
};
}
相关推荐
- **创建代理函数**:使用`createDelegate`方法创建代理函数,可以在不立即执行的情况下指定函数的作用域。 6. **自定义事件参数**: - 通过`scope`参数指定作用域。 - 使用`Function.prototype.createDelegate`...
此外,Microsoft AJAX Library还对Function对象进行了扩展,引入了如createDelegate、extend和implement等方法。createDelegate用于创建一个函数的代理,使得函数可以被调用时保持正确的上下文;extend和implement则...
4. **创建委托(Delegate)**:由于C#是强类型语言,我们需要创建一个与目标函数签名匹配的委托类型,然后使用`Delegate.CreateDelegate`方法将其与`MethodInfo`关联。 ```csharp // 假设目标函数为无返回值,接受...
然后,我们可以通过`Delegate.CreateDelegate`创建一个指向方法的委托,以便于调用: ```csharp MethodInfo methodInfo = type.GetMethod("MethodName"); Delegate del = Delegate.CreateDelegate(typeof(Action), ...
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed)); } ``` 在 onQuerySucceeded 方法中,我们可以获取当前用户所属的...
MyDelegate del = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), instance, "MyMethod"); del.DynamicInvoke(); ``` 接下来,关于性能比较。通常,反射比直接静态编译的代码慢,因为它涉及更多的元数据...
Delegate myDelegate = Delegate.CreateDelegate(typeof(Action), instance, "MyEventMethod"); myDelegate.DynamicInvoke(); ``` 总结,C#的反射功能强大且灵活,但应谨慎使用,因为它可能会带来性能开销。在...
然后,使用`Delegate.CreateDelegate()`方法创建一个指向目标方法的委托实例,并将其关联到菜单项的`Click`事件。 5. **添加到菜单**:最后,将这些菜单项添加到菜单条目或子菜单中。 这个DEMO可能包含一个简单的...
Delegate myDelegate = Delegate.CreateDelegate(typeof(Action), obj, "MyMethod"); myDelegate.DynamicInvoke(new object[] { arg1, arg2 }); ``` 总结,C#反射提供了一种强大且灵活的方式来处理运行时的类型...
Delegate cSharpDel = Delegate.CreateDelegate(typeof(YourCSharpDelegateType), cSharpMethodInfo); cSharpDel.DynamicInvoke(parameters); ``` 以上步骤完成后,你就可以在C# Winform应用中安全地动态调用DLL了...
9. **委托创建(Delegate.CreateDelegate)**:反射可以用于创建委托实例,将方法绑定到一个事件处理程序: ```csharp MethodInfo handlerMethod = myType.GetMethod("EventHandlerMethod"); Delegate ...
4. **完成并执行**:最后,通过`ILGenerator`的`EndMethod()`方法结束方法定义,然后通过`DynamicMethod`的`CreateDelegate`方法创建委托并执行。 举例来说,以下代码展示了如何使用Emit动态创建一个简单的加法方法...
概述 本文涉及到的反射优化的途径有如下两种: 通过Delegate.CreateDelegate()创建委托进行优化 通过.NET4的动态运行时进行优化 如果您还知道其他更加有效的优化途径,请不吝赐教! 准备工作 今天我们总计要对比五...
* 委托类型可以使用`Delegate.CreateDelegate`方法来创建委托实例。 3. 成员的传递 在使用系统API时,需要将C#中的类型转换成可以被系统API识别的类型。例如,C#中的字符串类型需要转换成非托管的字符串类型,以便...
你可以通过`EventInfo`类来获取和触发事件,通过`Delegate.CreateDelegate()`创建委托实例,实现动态绑定和调用事件处理器。这在处理不固定事件源或事件处理逻辑时非常有效。 另外,反射还可以用于元编程,即在运行...
2. 动态委托:还可以通过Delegate的CreateDelegate方法创建一个指向特定方法的委托,然后通过委托调用方法。 五、访问字段和属性 1. FieldInfo类用于访问字段,通过Type对象的GetField或GetFields方法获取FieldInfo...