V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
yqf3139
V2EX  ›  问与答

javascript:请问一种方案,标记一个不受自己控制的 typed array 是否存在修改

  •  
  •   yqf3139 · 2015-08-25 16:51:47 +08:00 · 1574 次点击
    这是一个创建于 3405 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有这么一个需求,给定一个很长的 typed array ,由其他人的逻辑修改,在一个循环中进行多次修改,而我需要多次做记录,即上次到目前是否有修改,将整个数组发回去,不需要找出具体的修改内容.如何在不改动其他人的代码的同时用最小的成本做到这一切?

    预期其他人的修改是通过 set 函数和[]操作符.就希望在这些函数调用时插入一个设置 dirty 的语句.
    set 函数可以轻易修改,但[]操作符却因为 javascript 操作符不能重载而难以追踪到是否有数据修改.

    目前已经作废的想法如下:
    1.所有需要遍历数组的办法比较低效,还要每次复制原数组.
    2.查到可以使用 Array.observe (),可以获得更新的回调,不过发现是异步的,而这样的话在回调之前我便已经需要对这个数组做判断了,而且似乎比较重量级,性能消耗大.
    3.查到可以使用 Object.defineProperty ,注册对应下标的 get , set 函数,不过似乎需要针对每个下标都注册函数,而且发现这个方法对于 typed array 无效,对于 ArrayBuffer , Object 和 Array 可行.
    4.可以写一个 Proxy 将这个数组包在里面,不过没有办法修改其他人的代码,没办法修改引用为新的 Proxy .

    我还注意到 typed array 中有一 ArrayBuffer 成员,不过似乎对这个 buffer 注册没有用处.

    求教是否还有其他办法.
    1 条回复    2015-08-25 21:00:35 +08:00
    yqf3139
        1
    yqf3139  
    OP
       2015-08-25 21:00:35 +08:00
    有一个解决方法,想到可以在一开始把 typed array 的构造函数给覆盖重写。就可以实现一个 Proxy 来拦截 set 和 get 了。但直接在 typed array 上动态重写是无效的,不清楚原因。

    实现代码:

    <script src="https://gist.github.com/yqf3139/0f05621ae09be61d373f.js"></script>

    console.time ('a');for (var ii=0;ii<1000000;ii++){bb[ii%10] = bb[ii%10]+ii;};console.timeEnd ('a');
    VM4445:2 a: 4029.594ms
    console.time ('a');for (var ii=0;ii<1000000;ii++){a[ii%10] = a[ii%10]+ii;};console.timeEnd ('a');
    VM4446:2 a: 2374.783ms

    性能损失还好。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2733 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:58 · PVG 21:58 · LAX 05:58 · JFK 08:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.