我們經常會遇到,將腳本中定義的多個參數打包到一個數組中,然後將這個數組傳給一個組件方法。javascript和vbscript定義數組的方式是不同的。vbscript中的數組採用的是自動化兼容類型SAFEARRAY,對它進行遍歷是很方便的。下面我們重點看看javascript中的數組如何進行遍歷。
一、javascript腳本中數組的定義
javascript中的數組更像是一個Object對象。在javascript中,可以按數值索引給一個數組元素賦值,也可以通過名稱索引給數組元素賦值,如下:
var oParams=new Object();
oParams["LoginName"]="test";
oParams["Password"]="123";
oParams["VerifyCode"]="12PQ";
這樣賦值的好處是,每一個元素都可以標識一個明確的意義。
將oParams傳入組件方法oSoapClient.Execute
oSoapClient.Execute("UserLogin",oParams,fn_login_result,null);二、動態腳本的祕密武器--IDispatchEx接口
對於一個基本的Object對象,即可以動態的增加或刪除屬性、方法,也可以生成一個自定義的類,完全基於一個IDispatchEx接口。IDispatchEx是IDispatch的擴展,爲實現動態腳本的一些動態特性量身定製。除了提供IDispatch接口的所有方法之外,IDispatchEx還額外提供以下幾個特性:
- Add new members to an object ("expando") — use GetDispID with the fdexNameEnsure flag.
- Delete members of an object — use DeleteMemberByName or DeleteMemberByDispID.
- Case-sensitive dispatch operations — use fdexNameCaseSensitive or fdexNameCaseInsensitive.
- Search for member with implicit name — use fdexNameImplicit.
- Enumerate DISPIDs of an object — use GetNextDispID.
- Map from DISPID to element name — use GetMemberName.
- Obtain properties of object members — use GetMemberProperties.
- Method invocation with this pointer — use InvokeEx with DISPATCH_METHOD.
- Allow browsers that support the concept of name spaces to obtain the name space parent of an object — use GetNameSpaceParent.
下面,我們就通過GetNextDispID、GetMemberName和InvokeEx三個方法實現對數組的遍歷。
三、遍歷
VARIANT varParams; //這是腳本傳入的參數數組
//如果傳入的類型不是VT_DISPATCH就退回出錯信息
if(varParams.vt!=VT_DISPATCH)
return E_INVALIDARG;
//取得IDispatchEx接口
CComPtr<IDispatchEx> pDispEx;
HRESULT hr=varParams.pdispVal->QueryInterface(IID_IDispatchEx,(void**)&pDispEx);
if(FAILED(hr))
return E_INVALIDARG;
//枚舉所有的屬性
DISPID dispid;
//取得第一個元素的DISPID
hr = pDispEx->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid);
while (hr == NOERROR)
{
//元素名稱
CComBSTR bstrName;
hr = pDispEx->GetMemberName(dispid, &bstrName);
if (FAILED(hr))
return E_FAIL;
//元素值
CComVariant vValue;
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
hr = pDispEx->InvokeEx(dispid, LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET, &dispparamsNoArgs,
&vValue, NULL, NULL);
if(FAILED(hr))
return E_FAIL;
//取得下一個元素的DISPID
hr = pDispEx->GetNextDispID(fdexEnumAll, dispid, &dispid);
}