Forum Discussion

Philip_Baird's avatar
Philip_Baird
Community Expert
11 years ago

Script Extension corrupts native JScript Array


Hi, I have written a Script Extension that wraps the json2.js library.


 


I have encountered a problem where passing a JScript object that contains a native JScript Array from a Script Unit to the Script Extension to be parsed to JSON, the Array is being incorrectly cast to an object which causes json2 to produce incorrect JSON.


 


For example, in the following code (where RJSON.JSON is a Script Unit in which json2.js is wrapped):


 


function testToJSON() {


  var obj = {


    "arr": [ 123, 456 ]


  }


  Log.Message( RJSON.JSON.toJSON( obj ) ); // Correctly Logs {"arr":[123,456]}


  Log.Message( JSON2.toJSON( obj ) ); // Incorrectly Logs {"arr":{"0":123,"1":456}}


}


 


RJSON.JSON.toJSON( obj ) produces the correct JSON {"arr":[123,456]}


 


whereas the call to the Script Extension JSON2 JSON2.toJSON( obj ) produces incorrect JSON {"arr":{"0":123,"1":456}}


 


In both cases, the parsing code json2 is identical, the only difference is one is in a Script Unit and the other a Script Extension.


 


Is this expected behaviour? I would not have expected JScript objects to be corrupted in this way.


 


Regards,


Phil Baird

2 Replies

  • Hi Phil.



    I can only verify that passing native array back and forth thru script extension calls does not convert it into associative array.



    I've never faced to JSON parser before and may only guess that parser possibly uses some stuff (object prototype properties and/or types?) which are not available in script extensions (thus delivering wrong parsing result).




    Regards,

    Andrey
  • Philip_Baird's avatar
    Philip_Baird
    Community Expert

    I have found it actually has nothing to do with the JSON parser, there is a problem with Arrays as I have bundled underscore.js in a Script Extension and the _.isArray() method is returning false negatives, i.e. it returns false if the object passed in is an Array, which is horribly wrong.


     


    I have the following code in a Script Unit as well as in a Script Extension (originally from underscore.js):


     


    function isArray( obj ) {


      var ObjProto = Object.prototype;


      var toString = ObjProto.toString;


      Log.Message( "Type " + toString.call( obj ) );


      return toString.call( obj ) === '[object Array]';


    }


     


     


    I then call this function from each source in another Script Unit as such:


     


    function testArray() {


      var arr = [ 123, 456 ];


      Log.Message( SRC_TestArray.isArray( arr ) ); // Call Script Unit


      Log.Message( Test.TestArray.isArray( arr ) ); // Call Script Extension


    }


     


    This provides the following output:


     


    Type [object Array]


    True


    Type [object Object]


    False


     


    which proves that Arrays are somehow being cast to some sort of object.


     


    This is a serious problem for me, my code behaves differently (in this case, completely incorrect) depending on where it is executed.


     


    As a Developer, I need my code to execute consistently regardless of source so I can have confidence my test code is correct and not introducting potential errors.


     


    At this point in time, I can have no confidence that passed in Arrays are treated correctly in Script Extensions.


     


    Regards,


    Phil Baird