在 SpiderMonkey 中用 C 創建一個非函數對象,卻能在 JavaScript 中像函數一樣調用(如 hash(key))。關鍵在於 JSClass 結構的 call 字段設置回調,並在回調中通過 argv[-2] 獲取被調用對象(callee)。
static JSBool call_hash(JSContext* cx, JSObject* obj, uintN argc, JSval* argv, JSval* rval)
{
// obj 是全局對象,非 callee
*rval = JSVAL_NULL;
return JS_TRUE;
}
static JSClass hash_class = {
"Hash", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
finalize_hash,
0, 0,
call_hash, // 關鍵:設置 call 回調
0, 0, 0, 0, 0
};
官方文檔未說明。經郵件列表求證,**引擎調用 call 時,argv[-2] 即為被調用對象本身**(callee)。此為非文檔化行為,屬實現細節,升級風險較高。
因 API 混亂、非文檔化行為依賴等原因,最終決定放棄 SpiderMonkey,轉向其他腳本引擎(如 V8、Lua、ChakraCore)。