對于 C++ 來說,存在函數(shù)重載,例如:
void CCNode::setScale(float scale)
void CCNode::setScale(float scaleX,float scaleY)
這兩個函數(shù)的函數(shù)名是一樣的,但是參數(shù)表不同。最終在編譯器編譯后的函數(shù)簽名不一樣。
但是在 JavaScript 中并沒有這種機制。怎么破?存在兩種情況:
第一種、JS 需要調(diào)用重載的 C++ 函數(shù)接口 我們就以上面的函數(shù)為例,來看看在 cxx-generator 的自動生成代碼中,函數(shù)重載是如何處理的。打開 jsb_cocos2dx_auto.cpp,找到如下代碼:
JSBool js_cocos2dx_Node_setScale(JSContext *cx, uint32_t argc, jsval *vp)
{
jsval *argv = JS_ARGV(cx, vp);
JSBool ok = JS_TRUE;
JSObject *obj = NULL;
cocos2d::Node* cobj = NULL;
obj = JS_THIS_OBJECT(cx, vp);
js_proxy_t *proxy = jsb_get_js_proxy(obj);
cobj = (cocos2d::Node *)(proxy ? proxy->ptr : NULL);
JSB_PRECONDITION2( cobj, cx, JS_FALSE, "js_cocos2dx_Node_setScale : Invalid Native Object");
do {
if (argc == 2) {
double arg0;
ok &= JS_ValueToNumber(cx, argv[0], &arg0);
if (!ok) { ok = JS_TRUE; break; }
double arg1;
ok &= JS_ValueToNumber(cx, argv[1], &arg1);
if (!ok) { ok = JS_TRUE; break; }
cobj->setScale(arg0, arg1);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
} while(0);
do {
if (argc == 1) {
double arg0;
ok &= JS_ValueToNumber(cx, argv[0], &arg0);
if (!ok) { ok = JS_TRUE; break; }
cobj->setScale(arg0);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
} while(0);
JS_ReportError(cx, "js_cocos2dx_Node_setScale : wrong number of arguments");
return JS_FALSE;
}
只是通過 argc 參數(shù)簡單判斷了一下參數(shù)個數(shù),然后就執(zhí)行對應(yīng)的分支代碼就好了。但是如果遇到參數(shù)個數(shù)相同,而類型不同的情況呢?尚不得而知。
第二種、不需要調(diào)用 C++ 函數(shù)接口,直接在 JS 層代碼中模擬一下函數(shù)重載。這個就要利用 JS 語言的一些特性了。我們直接看 Cocos2d-html5 中的對應(yīng)代碼。哦,no,因為 html5 里面關(guān)于 CCNode::setScale 函數(shù)寫了一點雜技代碼。所以我們改成看 setPosition 函數(shù)吧。也是一樣的。
setPosition:function (newPosOrxValue, yValue) {
var locPosition = this._position;
if (arguments.length == 2) {
locPosition._x = newPosOrxValue;
locPosition._y = yValue;
} else if (arguments.length == 1) {
locPosition._x = newPosOrxValue.x;
locPosition._y = newPosOrxValue.y;
}
this.setNodeDirty();
},
可以看到,該代碼使用了 JS 的 arguments 來判斷參數(shù)個數(shù),然后執(zhí)行對應(yīng)的分支代碼。
好了,重載就說道這里,下篇繼續(xù)~