Ecmascript [[Get]]没有使用代理getPrototypeOf - 行为不一致?

时间:2017-02-03 07:06:28

标签: ecmascript-6

根据ecmascript spec obj。[[get]] 解析如下:

  1. 首先检查对象是否具有密钥( getOwnProperty
  2. 如果没有,请遵循 Object.getPrototypeOf(obj)[[get]]
    ...(省略其他步骤)
  3. 但是,代理的spec。[[get]] 会执行以下操作:

    ...(省略一些步骤)
    7.如果缺少 [[get]] 的陷阱,请按照目标。[[get]]

    与getPrototype结合使用会导致以下不一致: 对象可以是某种类型T的实例,但没有该类型的方法。

    示例如下

    var o = {};
    var p = new Proxy(o, { 
      getPrototypeOf(target) { return Array.prototype;} 
    });
    
    console.log(p instanceof Array) //true
    console.log(p.push) //undefined

    从技术上讲,可以通过编写 [[get]] 处理程序来修复此行为,但这可能会将性能降低到无法使用的级别*。

    *试验受红宝石启发的模块系统。这表明每个模块函数调用都将运行一个或多个代理。[[get]] s,它将性能降低到至少1/10。

    编辑:非常粗略的基准测试表明130x(实例化) - 500x(函数调用)对我自己实现的性能损失。

1 个答案:

答案 0 :(得分:1)

我不相信它本身就不一致:你刚刚发现了许多不变量中的一个"代理允许您违反。 (吓唬引号,因为它不是规范中的invariants之一。)

如果你想[[Get]]的行为与[[GetOwnPrototype]]所隐含的行为相匹配,你可以像你说的那样编写自己的处理程序,或者只是不在[[GetOwnPrototype]]上设置处理程序