VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 11071|回复: 0

[分享] SpiderMonkey_31.2.0版编程笔记 八__数组操作

[复制链接]
04_avatar_middle
最佳答案
0 
online_vip 发表于 2015-9-18 21:13:43 | 显示全部楼层 |阅读模式
本帖最后由 liehuo 于 2015-9-18 21:17 编辑

说了这么多,我好像没有说spidermonkey引擎的数组,今天就来说说数组操作的方法。在JavaScript里数组和对象是相通的。你可以通过数组的方法来访问对象,比如var obj={name:"libai",age:22}你可以通过obj.name来访问name的值,也可以通过数组方式obj["name"]来访问name的值,不过要加个双引号或者单引号。也可以通过对象的方法来访问数组,比如有一个数组var arr=[2,3,4,5],我们可以这样访问:arr[0]来访问第一个元素,也可以通过对象的方式arr["0"]来访问第一个元素的值,不过也要加个双引号或者单引号。明白了这点你就可以把数组当作一个对象,里面的元素当作属性。那JS_GetProperty这个函数就可以把数组的元素当作属性来访问了。属性名就是下标,不过要用双引号括起来。例如:
  1.         char* script = "var arr=[2,3,4,5];";
  2.         const char *filename = "noname";
  3.         int lineno = 1;
  4.         bool ok = false;
  5.         ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno);//执行脚本
  6.         RootedValue rval(cx); //创建一个RootedValue变量用于接收执行的结果,而这个结果的值是一个被根化的值
  7.         JS_GetProperty(cx, global, "arr", &rval);//数组也是对象,先获取数组这个对象
  8.         uint32_t len = 0;
  9.         if (rval.isObject())
  10.         {
  11.                 RootedObject arrobj(cx, JSVAL_TO_OBJECT(rval));
  12.                 JS_GetProperty(cx, arrobj, "3", &rval);//再获取数组对象里的下标为3的元素
  13.                 printf("%d\n", rval.toInt32());
  14.         }
复制代码

刚才说的是如何访问数组,现在说说如何通过spidermonkey引擎来定义一个数组。函数JS_NewArrayObject就可以定义一个数组,原型如下:
JSObject * JS_NewArrayObject(JSContext *cx, size_t length);
第一个参数是上下文,第二个是数组长度。从参数上看并没有具体某个元素的值,它只是定义了一个一定长度的空数组。要定义其中元素的值也有个函数:JS_DefineElement,原型如下:
bool JS_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, jsval value,  JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
参数obj就是JS_NewArrayObject返回的数组对象,参数index就是下标,参数value就是你要指定的值是多少,看代码吧:
  1.         JSObject *arrObj = JS_NewArrayObject(cx, 5);
  2.         RootedObject rotObj(cx, arrObj);
  3.         JS_DefineElement(cx, rotObj, 0, INT_TO_JSVAL(18), nullptr, nullptr, JSPROP_ENUMERATE);
  4.         JS_DefineElement(cx, rotObj, 4, INT_TO_JSVAL(17), nullptr, nullptr, JSPROP_ENUMERATE);
  5.         RootedId id2(cx, INT_TO_JSID(4));
  6.         JS_GetPropertyById(cx, rotObj, id2, &rval);
  7.         int n = rval.toInt32();
  8.         printf("arrObj[4]=%d\n", n);
复制代码
当然定义一个数组不止这一种方法,还有其它的方法,具体是怎么样的,还是看完整的代码,更有仔细看注释说明:
  1. #include "stdafx.h"
  2. #include "include/jsapi.h"
  3. #pragma comment(lib,"lib/mozjs-31.lib")//这里直接用这种方式,是为了观看方便
  4. using namespace JS;
  5. static JSClass global_class = {
  6.         "global",
  7.         JSCLASS_GLOBAL_FLAGS,
  8.         JS_PropertyStub,          //增加属性
  9.         JS_DeletePropertyStub,    //删除属性
  10.         JS_PropertyStub,          //获取属性
  11.         JS_StrictPropertyStub,    //设置属性
  12.         JS_EnumerateStub,
  13.         JS_ResolveStub,
  14.         JS_ConvertStub
  15. };
  16. void ExecScript(JSContext *cx)
  17. {
  18.         JSObject *obj = JS_NewGlobalObject(cx, &global_class, nullptr, FireOnNewGlobalHook);//创建一个新的JS对象,用作一个全局对象,但是要被根化,这里没有被根化。
  19.         RootedObject global(cx, obj);//在当前的上下文环境,用创建的全局对象创建根化的全局对象
  20.         JSAutoCompartment ac(cx, global);//进入新全局对象的隔室,好像干什么坏事总是见不得人,非要躲在包厢里做坏事一样
  21.         JS_InitStandardClasses(cx, global);//初始化全局对象和其它js里的常规对象

  22.         char* script = "var arr=[2,3,4,5];";
  23.         const char *filename = "noname";
  24.         int lineno = 1;
  25.         bool ok = false;
  26.         ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno);//执行脚本
  27.         RootedValue rval(cx); //创建一个RootedValue变量用于接收执行的结果,而这个结果的值是一个被根化的值
  28.         JS_GetProperty(cx, global, "arr", &rval);//数组也是对象,先获取数组这个对象
  29.         uint32_t len = 0;
  30.         if (rval.isObject())
  31.         {
  32.                 RootedObject arrobj(cx, JSVAL_TO_OBJECT(rval));
  33.                 JS_GetProperty(cx, arrobj, "3", &rval);//再获取数组对象里的下标为3的元素
  34.                 printf("arr[3]=%d\n", rval.toInt32());
  35.                 printf("****************************************\n");
  36.                 JS_GetArrayLength(cx, arrobj, &len);//获取数组的长度
  37.                 for (int i = 0; i < len; i++)         //遍历数组元素
  38.                 {
  39.                         RootedId id(cx, INT_TO_JSID(i));
  40.                         JS_GetPropertyById(cx, arrobj, id, &rval);//通过id获取属性,另外一种方法获取属性值
  41.                         int a = rval.toInt32();
  42.                         printf("arr[%d]=%d\n", i, a);
  43.                 }
  44.                 printf("****************************************\n");
  45.         }
  46.         //第一种方式定义数组
  47.         JSObject *arrObj = JS_NewArrayObject(cx, 5);
  48.         RootedObject rotObj(cx, arrObj);
  49.         JS_DefineElement(cx, rotObj, 0, INT_TO_JSVAL(18), nullptr, nullptr, JSPROP_ENUMERATE);
  50.         JS_DefineElement(cx, rotObj, 4, INT_TO_JSVAL(17), nullptr, nullptr, JSPROP_ENUMERATE);

  51.         RootedId id2(cx, INT_TO_JSID(4));
  52.         JS_GetPropertyById(cx, rotObj, id2, &rval);
  53.         int n = rval.toInt32();
  54.         printf("arrObj[4]=%d\n", n);
  55.         printf("\n");
  56.         //第二种方式定义数组,用一个CallArgs
  57.         //Value *vec = (Value*)JS_malloc(cx, 5 * sizeof(jsval));
  58.         Value vec[5] = {0};
  59.         for (int i = 0; i < 5; i++)
  60.         {
  61.                 vec[i] = INT_TO_JSVAL(i + 1);
  62.         }
  63.         /*这里下面代码为什么vec要减2,看一下这个函数的实现方法就知道了
  64.         CallArgs CallArgsFromVp(unsigned argc, Value *vp)
  65.         {
  66.                 return CallArgs::create(argc, vp + 2);
  67.         }
  68.         原来它里面又调用了另外一个函数,吧传进的指针给加了2,这样一来就不是从首地址开始的了,所以我们减掉2,就可以从首地址开始了
  69.         */
  70.         CallArgs args = CallArgsFromVp(5, vec - 2);
  71.         HandleValueArray valueArr(args); //HandleValueArray的一个构造函数,用CallArgs类型参数构造
  72.         JSObject* argsObj = JS_NewArrayObject(cx, valueArr);
  73.         RootedObject robj_args(cx, argsObj);
  74.         RootedId id3(cx, INT_TO_JSID(2));
  75.         JS_GetPropertyById(cx, robj_args, id3, &rval);
  76.         int n2 = rval.toInt32();
  77.         printf("argsObj[2]=%d\n", n2);
  78.         printf("\n");
  79.         //第三种方式定义数组,用AutoValueVector
  80.         AutoValueVector vtor(cx);
  81.         for (int i = 0; i < 5; i++)
  82.         {
  83.                 vtor.append(INT_TO_JSVAL(i));
  84.         }
  85.         HandleValueArray valuevector(vtor);//HandleValueArray的另外一个构造函数,用AutoValueVector类型参数构造
  86.         JSObject* vecObj = JS_NewArrayObject(cx, valuevector);
  87.         RootedObject robj_vector(cx, vecObj);
  88.         RootedId id4(cx, INT_TO_JSID(1));
  89.         JS_GetPropertyById(cx, robj_vector, id4, &rval);
  90.         int n3 = rval.toInt32();
  91.         printf("vecObj[1]=%d\n", n3);
  92.         printf("\n");
  93. }
  94. int _tmain(int argc, _TCHAR* argv[])
  95. {
  96.         JS_Init();     //初始化JS引擎,一定要有这步,不然其它的操作都是扯淡
  97.         JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024, JS_USE_HELPER_THREADS);//创建运行时,是不是跟以前的不一样了
  98.         if (!rt)
  99.                 return 1;
  100.         JSContext *cx = JS_NewContext(rt, 8192);//创建一个JS上下文,与运行时关联起来
  101.         if (!cx)
  102.                 return 1;
  103.         //****************************************************************************************
  104.             ExecScript(cx);
  105.         //****************************************************************************************
  106.         JS_DestroyContext(cx);//销毁创建的上下文
  107.         JS_DestroyRuntime(rt);//销毁释放运行时
  108.         JS_ShutDown();        //释放js引擎使用的所有资源
  109.         return 0;
  110. }
复制代码
程序运行结果如图:
SpiderMonkey_31.2.0版编程笔记 八__数组操作

上一篇:SpiderMonkey_31.2.0版编程笔记 七__类操作




上一篇:Directshow 中的视频捕捉,非常全的资料
下一篇:截屏程序,VC6环境运行
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-10-27 14:22

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表