接上一次的帖子http://topic.csdn.net/u/20090407/14/07d7b3dd-7c7a-4eb8-8365-220dacaf2c4e.html在遍历JSON的属性成员的时候,对于{}对象 和 数组[], 得到的都是VT_DISPATCH也就是说,JS和VBS不同, JS的数组Array也是一个原型对象,不是SAFEARRAY
它的属性名称就是数组的index. 比如 0:"22",1:"dsa",2:"XX"那么,我在得到这个DISPATCH后,如何判断它在JS中是一个 {}的普通对象, 还是一个[]的Array对象?我目前的做法很笨, 如果发现属性名称是阿拉伯数字 AND 它由get_length属性 就认为是数组
由没有什么方法 相当与JS中的  XXX instanceof Array 之类的实现??

解决方案 »

  1.   

    要从JS对象的原型或者构造器入手,光判断get_length并不够,其它对象也一样可能出现这个属性。
    obj.protocol == Array.protocol
    或者
    obj.constructor == Array
    获取的这些属性全部都是IDispatch*
      

  2.   

    把IDispatch的js array转换成SAFEARRAY,然后取length等来判断个数...
      

  3.   

    如果是数组的话调用dispid为-4的方法应该会返回一个支持IEnumVARIANT接口的对象。
      

  4.   


    可能会有一些问题(要试验一下才知道),不光array支持枚举,普通的object也支持枚举,用for...in语句就能看出来,只不过这个语句的内部实现可能会有区别。
    for ( variable in [object | array] ) statements;
    对于数组,它枚举的是数组元素;对于对象,它枚举的是对象属性。
      

  5.   

    可行!
    BOOL bIsArray = FALSE; {
    UINT nArgErr(0);
    EXCEPINFO stExInfo;
    VARIANT varResult;
    DISPPARAMS stDispParams = { NULL, NULL, 0, 0 };
    HRESULT hr = pDispEx->Invoke( DISPID_NEWENUM
    , IID_NULL
    , LOCALE_SYSTEM_DEFAULT
    , DISPATCH_METHOD | DISPATCH_PROPERTYGET
    , &stDispParams
    , &varResult
    , &stExInfo
    , &nArgErr
    );
    if( SUCCEEDED(hr) )
    {
    if( varResult.vt == VT_UNKNOWN )
    {
    CComQIPtr<IEnumVARIANT> pEnum(varResult.punkVal);
    bIsArray = pEnum != NULL;
    }
    VariantClear(&varResult);
    }
    }
      

  6.   


    普通的{}确实能够通过 for in进行枚举, 不过我按照 蒋晟 的说法试验了一下, 对于{}对象, 是获取不到 NEWENUM 接口的
      

  7.   

    测试通过
    var pParam = {};
    pParam.AA= sPhone;
    pParam.GG = [1, 2, 3];
    pParam.TT = {Name:"1"};