我應該對標題做一個更詳細的解釋:用C語言在SpiderMonkey中產生一個在Javascript中可以當成函數被調用的對象,換句話說,就是一個非Function的對象,在JavaScript中可以被當成Function進行調用。例如,我有一個Hash對象,當我在var h = new Hash()之後,可以直接調用h(key),h並非一個函數對象,卻可以以這種函數調用的方式來獲取鍵key對應的值。
首先,必須要在創建這個Hash類的結構時,將JSClass中的”call”字段設置為相應的函數,如下:
static
JSBool call_hash(JSContext *cx, JSObject *obj, uintN argc, JSval *argv,
JSval *rval){
/* here the obj refers to the global object, not the callee itself */
*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,
0,
0,
0,
0,
0
};
現在,這裡有一個很關鍵的問題便是如何在SpiderMonkey調用call_hash函數的時候,能夠讓call_hash函數知道被調用的對象(callee)是誰。然而,Mozilla的官方文檔並沒有對此作出任何解釋。於是我在郵件列表中問了這個問題,有人給出了一個很特別的技巧——引擎調用call函數的時候,argv[-2]便是被調用者本身。
在把玩了Spidermonkey一段時間之後,我還是打算放棄spidermonkey,雖然這是一個很成熟很強大的腳本引擎,但是他的API還是有些混亂的,從本文的這個問題的解決方案就可以看得出來。