"函数对象"泛指以下内容:
函数对象可用于以下情况:
用户定义函数对象应遵循以下一般模式:
class YourClassName { Call(a, b) { ; 根据需要声明参数, 或数组*. ;... } __Call(method, args*) { if (method = "") ; 对 %fn%() 或 fn.() return this.Call(args*) if (IsObject(method)) ; 如果此函数对象作为方法被使用. return this.Call(method, args*) } ;... }
模式中各个部分适用于不同的使用情形, 如下:
this.()
的形式调用, 则, method
(方法名) 的值是空字符串.IsObject(method)
返回真, 并且 method
包含关于目标对象的引用. 如:若 x.y
指向 this
函数对象, 则 x.y()
→ this[x]()
→ this.__Call(x)
→ this.Call(x)
.上述过程可以直接在 __Call 中完成, 推荐使用 __Call 代替 Call 以便更好的迁移到 AutoHotkey v2 版本, 其会改变 %this%()
的行为及调用 CALL 的方法调用.
如果要定义多个函数对象类型, 则应将样板代码委托给基类(但如果您要将代码与其他人的组合使用, 请小心冲突). 例如:
class FunctionObject { __Call(method, args*) { if (method = "") return this.Call(args*) if (IsObject(method)) return this.Call(method, args*) } }
下面的例子定义了一个可以调用的函数数组; 调用时, 它依次调用数组的每个元素.
; 此示例需要上面的 FunctionObject class 才能工作. class FuncArrayType extends FunctionObject { Call(obj, params*) { ; 调用函数列表. Loop % this.Length() this[A_Index].Call(params*) } } ; 创建一个函数数组. funcArray := new FuncArrayType ; 向数组中添加函数(可以在任何位置完成). funcArray.Push(Func("One")) funcArray.Push(Func("Two")) ; 创建一个使用数组作为方法的对象. obj := {method: funcArray} ; 调用方法. obj.method("foo", "bar") One(param1, param2) { ListVars MsgBox } Two(param1, param2) { ListVars MsgBox }
行为像函数, 但只是将预定义的参数传递给另一个函数.
有两种建立绑定函数对象的方式:
调用绑定函数对象, 如下例所示. 不支持其他方法. 当绑定函数对象被调用时, 它调用绑定的函数或方法, 传递绑定的参数和后面跟着的调用者传递的任何参数. 例如:
fn := Func("RealFn").Bind(1) %fn%(2) ; 显示 "1, 2" fn.Call(3) ; 显示 "1, 3" RealFn(a, b) { MsgBox %a%, %b% }
ObjBindMethod() 用于绑定无法引用的方法. 例如:
file := FileOpen(A_ScriptFullPath, "r") getLine := ObjBindMethod(file, "ReadLine") MsgBox % %getLine%() ; 显示此文件的第一行.
更多复杂的例子, 请参阅 SetTimer.