<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1632085368384154" crossorigin="anonymous"></script><script src="https://autohotkey.top/gtag.js"></script></head> <body> <h1>函数对象</h1> <p>"函数对象" 通常表示以下任何一项:</p> <ul> <li><a href="Func.htm">Func</a> 或 <a href="../Functions.htm#closures">Closure</a> 对象, 它表示一个实际的<a href="../Functions.htm">函数</a>; 可以是内置函数也可以是脚本定义的函数.</li> <li>用户定义的对象, 可以像函数一样调用. 亦称为 "函数子".</li> <li>任何其他可以像函数一样调用的对象, 如<a href="#BoundFunc">绑定函数对象</a>或 COM 方法返回的 JavaScript 函数对象.</li> </ul> <p>函数对象可用于以下情况:</p> <ul> <li><a href="../lib/CallbackCreate.htm">CallbackCreate</a></li> <li><a href="GuiOnEvent.htm">Gui 事件</a></li> <li><a href="../lib/For.htm">For ... in</a></li> <li><a href="../lib/HotIf.htm">HotIf</a></li> <li><a href="../lib/Hotkey.htm">Hotkey</a></li> <li><a href="../lib/Hotstring.htm">Hotstring</a></li> <li><a href="../lib/InputHook.htm">InputHook</a> (OnEnd, OnChar, OnKeyDown, OnKeyUp)</li> <li><a href="Menu.htm#Add">Menu.Add</a></li> <li><a href="../lib/OnClipboardChange.htm">OnClipboardChange</a></li> <li><a href="../lib/OnError.htm">OnError</a></li> <li><a href="../lib/OnExit.htm">OnExit</a></li> <li><a href="../lib/OnMessage.htm">OnMessage</a></li> <li><a href="../misc/RegExCallout.htm">RegEx callouts</a></li> <li><a href="../lib/SetTimer.htm">SetTimer</a></li> <li><a href="../lib/Sort.htm">Sort</a></li> </ul> <p id="HasCall">要确定一个对象是否可被调用, 请使用以下方法之一:</p> <ul> <li>默认情况下, <code>Value.HasMethod()</code> 适用于所有的 AutoHotkey 值和对象, 但对于某些对象或类, 允许重写 HasMethod. 对于 COM 对象, 这通常会失败(抛出异常或产生错误的结果), 除非该 COM 对象实际上是来自其他进程的 AutoHotkey 对象.</li> <li><code>HasMethod(Value)</code> 适用于所有的 AutoHotkey 值和对象, 并且不能被重写, 但如果不能确定 <em>Call</em> 方法的存在, 则返回 false. An exception is thrown if <em>Value</em> is a <a href="../lib/ComObject.htm">ComObject</a>.</li> </ul> <h2 id="User-Defined">用户自定义</h2> <!-- TODO: Explain how a user-defined object could be useful --> <p>用户定义的函数对象必须包含一个 "函数" 实现的 <em>Call</em> 方法定义.</p> <pre>class YourClassName { Call(a, b) { <em>; 按需声明参数, 或 <a href="../Functions.htm#Variadic">array*</a>.</em> <em>;...</em> return c } <em>;...</em> } </pre> <p>这适用于 <em>YourClassName</em> 的 <em>实例</em>, 例如由 <code>YourClassName()</code> 返回的对象. 用 <code>static Call</code> 代替 <code>Call</code> 将覆盖 <em>YourClassName</em> 本身被调用时的情况.</p> <h3 id="User-Defined-Examples">示例</h3> <p>下面的例子定义了一个可以被调用的函数数组; 当被调用时, 它依次调用数组中的每个元素.</p> <pre>class FuncArrayType extends Array { Call(params*) { <em>; 调用函数列表.</em> for fn in this fn(params*) } } <em>; 创建一个函数数组.</em> funcArray := FuncArrayType() <em>; 向数组中添加函数(可以在任何位置完成).</em> funcArray.Push(One) funcArray.Push(Two) <em>; 创建一个使用数组作为方法的对象.</em> obj := {method: funcArray} <em>; 调用方法(One 和 Two 都会被调用).</em> obj.method("2nd") <em>; 将其作为函数调用.</em> (obj.method)("1st", "2nd") One(param1, param2) { ListVars MsgBox } Two(param1, param2) { ListVars MsgBox }</pre> <h2 id="BoundFunc">绑定函数对象</h2> <p>行为像函数, 但只是将预定义的参数传递给另一个函数.</p> <p>有两种建立绑定函数对象的方式:</p> <ul> <li>通过调用 <a href="Func.htm#Bind">Func.Bind</a> 方法, 其绑定参数值至一个函数.</li> <li>通过调用 <a href="../lib/ObjBindMethod.htm">ObjBindMethod</a> 函数, 其绑定参数值和方法名至目标对象.</li> </ul> <p>可以调用绑定函数对象, 如下例所示. 当绑定函数对象被调用时, 它调用绑定的函数或方法, 传递绑定的参数和后面跟着的调用者传递的任何参数. 未绑定的参数位置是从调用者的参数列表中指定的位置(从左到右). 例如:</p> <pre>fn := RealFn.Bind(1) <em>; 只绑定第一个参数</em> fn(2) <em>; 显示 "1, 2"</em> fn.Call(3) <em>; 显示 "1, 3"</em> fn := RealFn.Bind( , 1) <em>; 只绑定第二个参数</em> fn(2) <em>; 显示 "2, 1"</em> fn.Call(3) <em>; 显示 "3, 1"</em> fn(, 4) <em>; 错误: 'a' 被省略了</em> RealFn(a, b, c:="c") { MsgBox a ", " b }</pre> <p><a href="../lib/ObjBindMethod.htm">ObjBindMethod</a> 可用于绑定方法, 即使是在无法检索到方法本身的引用时. 例如:</p> <pre>Shell := ComObject("Shell.Application") RunBox := ObjBindMethod(Shell, "FileRun") <em>; 显示运行对话框.</em> RunBox</pre> <p>更多复杂的例子, 请参阅 <a href="../lib/SetTimer.htm#ExampleClass">SetTimer</a>.</p> <p>其他的属性和方法都是从 <a href="Func.htm">Func</a> 继承过来的, 但不反映目标函数或方法的属性(不需要作为一个函数来实现). BoundFunc 作为一个匿名的变量函数, 没有其他形式上的参数, 类似于下面的<a href="../Variables.htm#fat-arrow">胖箭头函数</a>:</p> <pre>Func_Bind(fn, bound_args*) { return (args*) =&gt; (args.InsertAt(1, bound_args*), fn(args*)) }</pre> <a href="https://dftg.net">dftg</a></body> </html>