【问题标题】:ES6 Proxy set property trap not firing for array lengthES6 代理设置属性陷阱未触发数组长度
【发布时间】:2016-06-23 10:37:54
【问题描述】:

使用 JavaScript ES6 代理时,在直接分配数组索引时不会触发 array.length 的 set 属性陷阱。

例如:

const proxy = new Proxy([], {
    set: function(obj, name, value) {
        console.log(`set: ${name}`);
        obj[name] = value;
        return true;
    }
});
proxy.push(0);
proxy[1] = 1;

Chrome 51 和 Firefox 47 输出:

设置:0
设置:长度
设置:1

虽然我期望:

设置:0
设置:长度
套装:1
设置:长度

这是符合规范的吗?我找不到这方面的任何信息。

【问题讨论】:

    标签: javascript ecmascript-6 es6-proxy


    【解决方案1】:

    将值分配给索引时,无需显式设置length 属性。之所以设置为push,确实是在specification中定义的:

    1. 重复,但项目不为空

      一个。从 items 中删除第一个元素,并让 E 成为元素的值。

      b.设 setStatus 为 Set(O, ToString(len), E, true)。

      c。 ReturnIfAbrupt(setStatus).

      d。设 len 为 len+1。

    2. 让 setStatus 为 Set(O, "length", len, true)。

    基本上:如果发生错误,则设置正确的长度,以防数组已经展开。

    【讨论】:

    • 这是一个很好的问题,但我看不出你是如何准确回答这个问题的 没有必要明确设置 length 属性何时一个值被分配给一个索引。 当我创建proxy[99] = 100 时,length 属性永远不会被set 困住,而是神奇地被get 困住,当console.log(proxy.length) 访问时返回100。所以我想 100 不是计算出来的,而是分配给 length 属性的值。当我随后执行.pop() 时,lengthset 困住并更新为 99。length 属性是如何变成 100 的。
    • @Redu .length 确实在when assigning to an index 的场景后面更新。您还可以认为每个实例都有一个神奇的 getter/setter .length,它始终知道项目(和孔)的数量。无论如何,此更新不能被代理捕获,因为它发生在数组实例(代理目标)本身上 - 与 pushpop 方法不同,它们对调用它们的(代理)对象进行显式分配开。
    • @Bergi 感谢您的关注。我什至尝试过defineProperty 陷阱,希望在索引处直接赋值可能会以某种方式重新定义length 属性,唉,这是不可能的。然后我想另一种方法是检查set 陷阱中的(prop === "length" || target.length <= prop) 以通过索引插入到数组末尾来捕获。这合理吗..?
    • @Redu 是的,这听起来很合理(但将 prop 转换为整数,并使用与我链接的规范部分相同的算法)。
    猜你喜欢
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多