javascript 有代理对象polyfill可用谷歌浏览器?

a5g8bdjr  于 2023-06-04  发布在  Java
关注(0)|答案(4)|浏览(155)

这可能吗其他浏览器怎么样?估计es6什么时候会“准备好”并推出?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
btw. https://github.com/tvcutsem/harmony-reflect代理不与当前的chrome(36.0.n)工作

50few1ms

50few1ms1#

您可以使用Object.definePropertyObject.observe来模拟代理。我开始想知道polyfill能支持多少功能,所以我写了一个实现(你可以在gist.github.com/mailmindlin/640e9d707ae3bd666d70上看到它)。我能够模拟所有不依赖于运算符重载的Proxy特性,这在JavaScript中是不可能的。
但是,您可以让getset和其他一些工作。你可以使用getter和setter来镜像目标对象的属性:

for (var property in target)
    Object.defineProperty(proxy, property, {
        get: function() {
            if ('get' in handler)
                return handler.get(target, property, proxy);
            else
                return target[property];
       },
       set: function(value) {
           if ('set' in handler)
               handler.set(target, property, value, proxy);
           else
               target[property] = value;
      }});

唯一的问题是getter和setter只应用于在代理初始化时为目标定义的属性,并且delete操作符将不起作用(如果您删除目标对象上的属性,代理仍将其枚举为属性;如果删除代理上的属性,则对象不会发生任何变化)。
要解决这个问题,您可以使用Object.observe,它将在对任一对象进行任何更改时调用。在www.example.com上快速查看一下caniuse.com,就会发现Object.observe在Chrome和Opera上都可用。如果您确实需要在其他浏览器上支持Proxy,您可以轮询targetproxy对象,以检查是否已创建或销毁任何属性:

var oldKeys = Object.keys(proxy);
setInterval(function() {
    var keys = Object.keys(proxy);
    for(var i in keys)
        if(!oldKeys.includes(keys[i]))
            //Trigger code for a new property added

    for(var i in oldKeys)
        if(!keys.includes(oldKeys[i]))
            //trigger code for a deleted property

    oldKeys = keys;

    //repeat for target object
}, 100);

如果您迫切需要代理的更多功能,您可以尝试覆盖Object.definePropertyObject.getOwnPropertyDescriptor等方法,但这可能会导致与其他脚本的兼容性问题,具体取决于您的操作方式。
简而言之,你可以做大部分你可能需要使用代理与polyfill。至于谷歌将其添加到他们的浏览器,我不知道。它显然曾经是V8引擎的一部分,但由于安全问题(没有人详细说明)而被删除,据我所知,基于this thread

mnemlml8

mnemlml82#

我已经创建了一个babel插件,它允许你这样做,但它带来了巨大的性能影响(对于每个属性访问)-这是更多的教育例子。
https://github.com/krzkaczor/babel-plugin-proxy

2nbm6dog

2nbm6dog3#

以下是Google Chrome团队创建的一个:https://github.com/GoogleChrome/proxy-polyfill
但这不是一个完整的实现。

0lvr5msh

0lvr5msh4#

更新:虽然我的答案提供了部分解决方案,但mailmindlin的solution证明了我的主要观点是错误的:你可以为Proxy创建polyfill。
不你不能因为Proxy依赖于几个语言语法元素的特殊(新)行为-即.运算符和[索引]运算符-它不能被polyfill模拟。
唯一的方法就是改变你使用的语法。例如,如果你想通过一个代理将所有字符串属性大写,你可以创建一个“proxy”对象,如下所示:

var object = ...
var proxy = {
    get: function proxyGet(key) {
        var res = object[key];
        if (typeof res === "string") {
            res = res.toUpperCase();
        }
        return res;
     }
}

但是,你仍然需要以不同的方式调用它:

proxy.get("myVar");

而不是

object.myVar;

proxy.myVar

这正是新的代理语法所支持的。
注意:你几乎可以创建一个只对方法有效的polyfill,方法是枚举对象的函数属性,并为每个属性在代理对象上创建一个代理函数;但是,这对非函数属性不起作用,因为您不能动态地影响访问它们的方式。

相关问题